这是一个编码示例:
#include <iostream>
using namespace std;
int main() {
float x = 0.1 * 7;
if (x == 0.7)
cout << "TRUE. \n";
else
cout << "FALSE. \n";
return 0;
}
这导致FALSE。但是,当我输出x时,确实输出为0.7。解释
答案 0 :(得分:7)
请阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic。
首先,0.1
是double
类型的文字。 IEEE 754双精度中最接近的可表示值为:
0.1000000000000000055511151231257827021181583404541015625
如果将其乘以7,IEE 754单精度中最接近的可表示值(因为您将其存储在float
中)是:
0.699999988079071044921875
正如您所看到的那样,几乎 0.7,但并不完全。然后将其转换为double
进行比较,最后比较以下两个值:
0.699999988079071044921875 == 0.6999999999999999555910790149937383830547332763671875
当然评估为false
。
答案 1 :(得分:1)
这是因为数字以二进制形式存储。在二进制中,你无法用有限多的位置精确地表示分数.1或.7,因为它们具有二进制的重复扩展。类似1/2的东西可以用表示.1来表示,但十进制的.1例如是.0001100110011 ....所以,当你切断这个数字时,你肯定会有舍入错误。
答案 2 :(得分:0)
==
运算符永远不应该比较双打和浮点数。数字不准确地存储在存储器中,因为在二进制中它们不必具有有限的表示(例如0.1)。
你会在这里看到它:
#include <iostream>
using namespace std;
int main() {
float x = 0.1 * 7;
cout << x-0.7;
return 0;
}
差异不是零,而是非常接近于零的东西。
答案 3 :(得分:0)
与每种数据类型一样,float表示为二进制数。有关确切表示,请参见此处:http://en.wikipedia.org/wiki/IEEE_floating_point
手动将十进制数转换为浮点数时,首先必须将其转换为固定点数。
将0.7转换为基数2(二进制):
0.7 = 0.101100110011 ......
如您所见,它在逗号后面有无穷大的数字,因此当将其表示为float数据类型时,某些数字将被截断。当将其转换回十进制时,这导致数字不完全为0.7。
在您的示例中,乘法产生的数字与文字“0.7”不同。
解决此问题:比较浮点数的相等性时使用epsilon:
if (x < 0.71f && x > 0.69f)