解释这个浮点行为

时间:2012-02-27 08:05:14

标签: c floating-point

请解释为什么下面的代码行为不同。

#include<stdio.h>
int main(){
 float a=0.1;
 if(a<0.1)
  printf("less");
 else 
  printf("greater than equal");
getchar();
}

Output:greater than equal

 #include<stdio.h>
 int main(){
 float a=0.7;
 if(a<0.7)
  printf("less");
 else 
  printf("greater than equal");
getchar();
}

Output:less与我的预期相反。

PS:这不是作业。

6 个答案:

答案 0 :(得分:10)

此处涉及两种不同的类型:floatdouble。您分配给float,然后double进行比较。

想象一下,floatdouble实际上是2位和4位十进制浮点类型。现在想象你有:

float a = 0.567123 // Actually assigns 0.57
if (a < 0.567123) // Actually compares 0.5700 with 0.5671
{
    // We won't get in here
}

float a = 0.123412; // Actually assigns 0.12
if (a < 0.123412) // Actually compares 0.1200 with 0.1234
{
    // We will get in here
}

显然这是对正在发生的事情的近似,但它解释了两种不同的结果。

如果没有更多信息,很难说你应该做什么 - 很可能你根本不应该使用floatdouble,或者那个您应该使用某种程度的容差进行比较,或者您应该在任何地方使用double,或者您应该接受某种程度的“不准确”,这只是系统工作方式的一部分。

答案 1 :(得分:4)

您无法可靠地在浮点数上使用比较运算符。

比较两个浮点数的好方法是使精度阈值相对于被比较的两个浮点数的大小。

类似的东西:

#include < math.h >
if(fabs(a - b) <= accurary_threshold * fabs(a))

好读:

答案 2 :(得分:3)

我建议你阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic。基本上在处理浮点数时,您应该始终检查数字是否相等,小于或大于某个其他数字,给定您已定义的精度(epsilon)。

答案 3 :(得分:2)

浮点数不准确。具体而言,您的号码不一定与浮点数进行比较。如果您使用“0.7f”代替“0.7”(至少在我的编译器上),相同的代码可以正常工作,但您通常应该与阈值进行比较,如前面的答案所述。

答案 4 :(得分:2)

#include<stdio.h>

int main() {
    float a = 0.7;
    if (a < 0.7)
        printf("less");
    else 
        printf("greater than equal");
    getchar();
}

非浮动常量类型double而不是float。例如,0.7double类型的浮动常量。

if (a < 0.7)

由于比较表达式中的右操作数是double类型,通常的算术转换适用,a值被提升为doubledoublefloat的精确度不同。在您的情况下,为了获得正确的结果,您应该使用类型为float的浮动常量。

if (a < 0.7f)

0.7ffloat类型的浮动常量。

答案 5 :(得分:0)

执行比较时,您将浮点(具有24位精度)与双精度(具有53位精度)进行比较。您的浮点值是通过从更精确的double值舍入来创建的。有时它会向下舍入,有时会向下舍入。它几乎不会是一样的。

再次尝试您的示例,但测试所有三种可能的结果:相等,更少和更大。

再次使用双击作为示例。

再次尝试你的例子并与浮动进行比较。