我正在进行计算,即将double转换为二进制,在此过程中会出现一个奇怪的问题,最终导致错误。所以当我发现结果错误时,我打印出小数部分。
分数部分的代码是这样的:
while(float_part != (int)(float_part)){
float_part -= (int)(float_part); //just leave fractional part
float_part *= 2; //float_part is a double
res = res + to_string(((int)(float_part))); //add to "res", which is a string
cout << float_part << "+" << length << "\n"; //to figure out why
length--; //the length is initialized to 32
if(length <= 0){
return "ERROR"; //if too long
}
}
然后我输入“28187281.525”(在上面的代码中只有.525事项),发现结果很奇怪:
1.05+32
0.1+31
0.2+30
0.4+29
0.8+28
1.6+27
1.2+26
0.4+25
0.799999+24
1.6+23
1.2+22
0.399994+21
0.799988+20
1.59998+19
1.19995+18
0.399902+17
0.799805+16
1.59961+15
1.19922+14
0.398438+13
0.796875+12
1.59375+11
1.1875+10
0.375+9
0.75+8
1.5+7
1+6
1101011100001101010010001.100001100110011001100110011
一开始没关系,但最终结果出错了!
为什么0.4 * 2变成0.799999 ..
有人知道原因吗?提前谢谢!
答案 0 :(得分:2)
浮点值的精度有限。您对它们执行的任何操作都可能引入小错误。您执行的操作越多,错误就越多。在您的情况下,您应该将浮点变量拆分为整数组件(符号,尾数和指数),并对这些整数执行任何操作。浮点通常以IEEE_754格式存储:
https://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers
答案 1 :(得分:1)
当您操纵无法准确表示的值时,这是有限精度算术的本质。
0.4 * 2变为0.7999999因为相同的原因1/3乘3变为0.9999999 - 你能用十进制做的最好代表1/3为0.333333如果你把它乘以3,你得到0.99999。您需要无限数量的数字才能得到确切的答案。