我无法理解为什么C ++除法的行为方式。我有一个简单的程序,将1除以10(使用VS 2003)
double dResult = 0.0;
dResult = 1.0/10.0;
我希望dResult为0.1,但我得到0.10000000000000001
感谢。
答案 0 :(得分:3)
因为所有大多数现代处理器都使用二进制浮点,它不能精确地表示0.1(没有办法将0.1表示为m * 2^e
整数m
和{{ 1}})。
如果您想查看“正确的值”,可以使用例如:
打印出来e
答案 1 :(得分:2)
Double和float与实数不同,这是因为实数有无穷大的值,但只有有限的位数才能用double / float表示它们。
您可以进一步阅读:what every computer scientist should know about floating point arithmetics
答案 2 :(得分:2)
无处不在的IEEE754浮点格式用科学记数法2表示浮点数,具有有限的尾数。由于像1/5(因此1/10)这样的分数在二进制科学记数法中没有有限多位数的表示,因此不能精确地表示值0.1。更一般地说,唯一可以精确表示的值是那些精确拟合成二进制科学记数法的值,其尾数为少数(例如24或53或64)二进制数字,并且是一个适当小的指数。
答案 3 :(得分:0)
使用整数,浮点数和双精度数可能会比较棘手。取决于您的目的。如果只想以漂亮的格式显示,则可以使用C ++ iomanipulator,precision,showpint,noshowpint。如果您尝试使用数值方法进行精确计算,则可能必须使用一些库来精确表示。如果您要乘以大量的小数和大数,则可能不得不停下来使用对数转换。这是一个小测试:
float x=1.0000001;
cout << x << endl;
float y=9.9999999999999;
cout << "using default io format " << y/x << endl;
cout << showpoint << "using showpoint " << y/x << endl;
y=9.9999;
cout << "fewer 9 default C++ " << y/x << endl;
cout << showpoint << "fewer 9 showpoint" << y/x << endl;
1
using default io format 10
using showpoint 10.0000
fewer 9 default C++ 9.99990
fewer 9 showpoint9.99990
在特殊情况下,您想使用双精度(可能是某些复杂算法的结果)来表示整数,则必须找出正确的转换方法。一旦遇到一种情况,我想使用一个双精度值来存储两种类型的值:-1,+ 1或(0-1)以使代码的内存使用效率更高(并且速度大的内存会降低性能) )。区分+1和val <1有点棘手。在这种情况下,我知道值<1的分辨率只有1/500,然后我可以安全地使用floor(val + 0.000001)取回1我最初存储的值。