参见下面的程序
#include<stdio.h>
int main()
{
float x = 0.1;
if (x == 0.1)
printf("IF");
else if (x == 0.1f)
printf("ELSE IF");
else
printf("ELSE");
}
这里有另一个程序
#include<stdio.h>
int main()
{
float x = 0.5;
if (x == 0.5)
printf("IF");
else if (x == 0.5f)
printf("ELSE IF");
else
printf("ELSE");
}
从这两个程序中我们都期望得到类似的结果,因为两者都没有改变,一切都是相同的,而且比较术语也相应地改变了。
但以上2个程序会产生不同的结果
第一个计划
ELSE
第二个计划
IF
为什么这2个程序表现不同
答案 0 :(得分:1)
这两个程序的行为因计算机和操作系统而异 - 您正在测试floats
的完全相等。
在内存中,floats
存储为binary
中的一串位 - 即二进制0.1(0.1b)表示十进制0.5(0.5d)。
类似地,
Binary | Decimal
0.1 | 2^-1 = 1/2
0.01 | 2^-2 = 1/4
0.001 | 2^-3 = 1/8
0.11 | 2^-1 + 2^-2 = 3/4
问题是某些小数字没有漂亮的浮点表示。 0.1d = 0.0001100110011001100110011 ... 这是无限长的。
所以,0.5在二进制文件中非常好用
0.5d = 0.1000000000000000...b
但0.1非常讨厌
0.1d = 0.00011001100110011...
现在,根据您的编译器,它可能假设0.1f是double
类型,它存储了0.0001100110011001100110011001100110011的无限序列...
因此它不等于float
版本,它会更早地截断序列。
另一方面,无论存储多少个小数位,0.5f都是相同的,因为它在第一个位置之后全部为零。
在C ++或C中比较float
或double
s的可接受方式是#define
一个非常小的数字(我喜欢称之为EPS,EPSILON的缩写)并替换
float a = 0.1f
if (a == 0.1f) {
printf("IF\n")
} else {
printf("ELSE\n")
}
与
#include <math.h>
#define EPS 0.0000001f
float a = 0.1f
if (abs(a - 0.1f) < EPS) {
printf("IF\n")
} else {
printf("ELSE\n")
}
实际上,这可以测试a是否足够接近0.1f而不是精确相等。对于99%的应用程序,这种方法运行得很好,但对于超敏感计算,需要一些涉及使用long double
或定义自定义数据类型的陌生技巧。
答案 1 :(得分:0)
您使用的是两种数据类型:double,自动在if(x=0.1)
)
(0.1为double),x为float。这些类型与存储价值的方式不同。 0.1不是0.1f,是0.100000000001(双)或0.09388383(某物)