我在C中遇到过两个程序,它们都比较浮点数但输出不同。
1)
InputStream is = getContentResolver().openInputStream(data.getData());
输出:ELSE IF
2)
#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");
}
输出:IF
为什么0.5不会提升为双倍,而0.1是?
答案 0 :(得分:4)
由于double
比float
宽,x == 0.1
被解释为(double) x == 0.1
。
这适用于0.5,因为0.5在二进制中是完全可表示的,因此(double) 0.5f
精确地产生0.5。另一方面,0.1具有an infinite-digit representation in binary,并且0.1f和0.1最终被舍入为不同的数字,这些数字与它们所持有的序列的初始数字的数量不同。
与十进制数字类比,您可以将上述情况视为尝试通过将其四舍五入为固定的十进制数字来记下1/3。使用5位有效数字表示,得到0.33333;选择一个10位数的结果为0.3333333333。现在,&#34;铸造&#34;五位数到十位数的结果为0.3333300000,这是一个与0.3333333333不同的数字。在同样的类比中,0.5 in就像十进制的1/10,分别表示为0.10000和0.1000000000,因此可以将其转换为另一种表示并返回而不改变其含义。
如果x
的内容是代码设置的标记值,则只需将其与0.1f
进行比较,而不是0.1
。如果是计算结果,请参阅Paul's answer了解比较浮点数的正确方法。
答案 1 :(得分:0)
将一个浮点数与另一个浮点数进行比较的正确方法是使用精确值,例如
#define EPS 0.00001
#define ABS(a) ((a)<0?-(a):(a))
if (ABS(a-b)<EPS)
...
这源于:
if (a == b) // "equal" of fp numbers is not well defined
if (a-b == 0) // so comparing with zero is also ill defined
if (ABS(a-b) < EPS) // and so we compare with this small precission