我有一些代码块:
float total = <some float>;
double some_dbl = <some double>;
total *= some_dbl;
这引发了我想要关闭的编译器警告,但我不喜欢关闭这样的警告 - 相反,我宁愿根据需要显式地转换类型。这让我思考......是一个 (float)(total * some_dbl)
比准确更准确 total * (float)some_dbl
?它是编译器还是平台特定的?
更好的代码示例(链接如下):
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main() {
double d_total = 1.2345678;
float f_total = (float)d_total;
double some_dbl = 6.7809123;
double actual = (d_total * some_dbl);
float no_cast = (float)(f_total * some_dbl);
float with_cast = (float)(f_total * (float)some_dbl);
cout << "actual: " << setprecision(25) << actual << endl;
cout << "no_cast: " << setprecision(25) << no_cast << endl;
cout << "with_cast: " << setprecision(25) << with_cast << endl;
cout << "no_cast, nextafter: " << setprecision(25) << nextafter(no_cast, 500.0f) << endl;
cout << endl;
cout << "Diff no_cast: " << setprecision(25) << actual - no_cast << endl;
cout << "Diff with_cast: " << setprecision(25) << with_cast - actual << endl;
return 0;
}
编辑:
所以,我给了他一个机会。通过我尝试的例子,我确实找到了一个快速的地方 total * (float)(some_dbl)
似乎 更多 准确。我认为这并非总是如此,而是抽奖的运气,或者编译器截断双精度以使其浮动,而不是舍入,从而导致可能更糟的结果。看到: http://ideone.com/sRXj1z
编辑2: 我确认使用了 std::nextafter
那 (float)(total * some_dbl)
返回截断的值,并更新链接的代码。这是非常令人惊讶的:如果在这种情况下编译器总是截断双打,那么你可以说 (float)some_dbl <= some_dbl
,然后暗示 with_cast <= no_cast
。但是,这是 不 案子! with_cast
不仅大于 no_cast
但它更接近实际值,这有点令人惊讶,因为我们在乘法发生之前丢弃信息。