我遇到浮点运算不精确的一些问题。我正在尝试根据加权公式计算得分,其中每个输入变量的重量大约是下一个重要值的20倍。然而输入是实数,所以我最终使用double来存储结果。下面的代码存在丢失E1和E2之间差异的问题。
此代码对性能敏感,因此我需要找到解决此问题的有效方法。我想把我的输入乘以一百然后再使用一个int(因为我认为这个就足够精确了),但我怀疑这是最好的解决方案,因此问题。
#include <iostream>
int main()
{
double score1, score2;
float a = 2.75 ;
float b = 5.25 ;
float c = 5.25 ;
float d = 2.75 ;
float E1 = 3 ;
float E2 = 6 ;
score1 = 20 * b - 1 * a + 0.05 * d /* - 0.0025 * c*/ + 0.0001 * E1 ;
score2 = 20 * b - 1 * a + 0.05 * d /* - 0.0025 * c*/ + 0.0001 * E2 ;
std::cout << score1 << std::endl;
std::cout << score2 << std::endl;
std::cin.get();
return 0;
}
//ouputs:
//102.388
//102.388
答案 0 :(得分:4)
cout << setprecision(number_of_digits) << score1 << endl;
答案 1 :(得分:3)
我想过将我的输入乘以一百然后再使用一个int(因为我觉得这很精确),但我怀疑这是最好的解决方案
考虑到你所展示的价值,我会说是。
答案 2 :(得分:1)
http://ideone.com/qqTB3向您显示差异并未丢失,但实际上与您期望的一样大(达到浮点精度,即双倍的15位十进制数字)。
答案 3 :(得分:1)
让我们看看这段代码中发生了什么:
score1 = 20 * b - 1 * a + 0.05 * d /* - 0.0025 * c*/ + 0.0001 * E1 ;
// Multiplication division happens first:
float tmp1 = static_cast<float>(20) * b; // 20 cast to float.
float tmp2 = static_cast<float>(1) * a; // 1 cast to float.
double tmp3 = 0.05 * static_cast<double>(d); // d converted to double as 0.05 is double
double tmp4 = 0.0001 * static_cast<double>(E1);// E1 cast to double as 0.0001 is double
// Addition and subtraction now happen
float tmp5 = tmp1 - tmp2;
double tmp6 = static_cast<double>(tmp5) + tmp3; // tmp5 cast to double as tmp3 is a double.
double tmp7 = tmp6 + tmp4;
score1 = tmp7;
如果我们在脑海中这样做:
tmp1 = 105.0
tmp2 = 2.75
tmp3 = 0.1375
tmp4 = 0.0003
tmp5 = 107.75
tmp6 = 107.8875
tmp7 = 107.8878
这些值应保持精度:
但是当你打印出来时,双精度的默认精度是3位小数。
std::cout << 107.8878;
> 107.888
所以设置精度:
std::cout << std::setprecision(15) << 107.8878 << "\n";
> 107.8878