C / C ++:1.00000 <= 1.0f =假
有人可以解释为什么1.000000
Can someone explain why 1.000000 <= 1.0f is false?
代码:
#include <iostream>
#include <stdio.h>
using namespace std;
int main(int argc, char **argv)
{
float step = 1.0f / 10;
float t;
for(t = 0; t <= 1.0f; t += step)
{
printf("t = %f\n", t);
cout << "t = " << t << "\n";
cout << "(t <= 1.0f) = " << (t <= 1.0f) << "\n";
}
printf("t = %f\n", t );
cout << "t = " << t << "\n";
cout << "(t <= 1.0f) = " << (t <= 1.0f) << "\n";
cout << "\n(1.000000 <= 1.0f) = " << (1.000000 <= 1.0f) << "\n";
}
结果:
t = 0.000000
t = 0
(t <= 1.0f) = 1
t = 0.100000
t = 0.1
(t <= 1.0f) = 1
t = 0.200000
t = 0.2
(t <= 1.0f) = 1
t = 0.300000
t = 0.3
(t <= 1.0f) = 1
t = 0.400000
t = 0.4
(t <= 1.0f) = 1
t = 0.500000
t = 0.5
(t <= 1.0f) = 1
t = 0.600000
t = 0.6
(t <= 1.0f) = 1
t = 0.700000
t = 0.7
(t <= 1.0f) = 1
t = 0.800000
t = 0.8
(t <= 1.0f) = 1
t = 0.900000
t = 0.9
(t <= 1.0f) = 1
t = 1.000000
t = 1
(t <= 1.0f) = 0
(1.000000 <= 1.0f) = 1
正如在注释中正确指出的, t
的值实际上并不是你在 1.00000
As correctly pointed out in the comments, the value of t
is not actually the same 1.00000
that you are defining in the line below.
使用 std :: setprecision(20)
以更高的精度打印t将显示其实际值: 1.0000001192092895508
。
Printing t with higher precision with std::setprecision(20)
will reveal its actual value: 1.0000001192092895508
.
避免这类问题的常见方法是不与 1
,但是使用 1 + epsilon
,其中epsilon是一个非常小的数字,也许是一个或两个大于您的浮点精度。
The common way to avoid these kinds of issues is to compare not with 1
, but with 1 + epsilon
, where epsilon is a very small number, that is maybe one or two magnitudes greater than your floating point precision.
所以你可以写你的for循环条件为
So you would write your for loop condition as
for(t = 0; t <= 1.000001f; t += step)
$ b
Note that in your case, epsilon should be atleast ten times greater than the maximum possible floating point error, as the float is added ten times.
如Muepe和Alain所指出的, t!= 1.0f的原因$ c>是
1/10
无法用二进制浮点数精确表示。
As pointed out by Muepe and Alain, the reason for t != 1.0f
is that 1/10
can not be precisely represented in binary floating point numbers.