【问题标题】:Explain this floating point behavior解释这种浮点行为
【发布时间】:2012-03-16 17:35:02
【问题描述】:

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

#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:这不是家庭作业。

【问题讨论】:

  • 下次搜索这个网站。这已经被问了 1000 次了。
  • 请解释为什么投反对票?
  • 您未能搜索此站点,这就是原因。
  • @Parminder 看看this question

标签: c floating-point


【解决方案1】:

这里涉及两种不同的类型: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,或者您应该接受某种程度的“不准确”作为系统工作方式的一部分。

【讨论】:

    【解决方案2】:

    您不能可靠地对浮点数使用比较运算符。

    比较两个浮点数的一个好方法是设置一个准确度阈值,该阈值与被比较的两个浮点数的大小相关。

    类似:

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

    好读:

    【讨论】:

    • @Parminder:现在你这样做了,这就是人们学习的方式,犯错误,但要从错误中学习,不要重蹈覆辙。 :)
    • 还有http://floating-point-gui.de/,我认为这是戈德堡文章的更易于管理的版本。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:
        #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 类型的浮点常量。

        【讨论】:

          【解决方案6】:

          执行比较时,您是在比较浮点数(精度为 24 位)和双精度数(精度为 53 位)。您的浮点值是通过从更精确的双精度值四舍五入创建的。有时它会四舍五入,有时它会四舍五入。它几乎不会是一样的。

          再次尝试您的示例,但要测试所有三个可能的结果:相等、小于和大于。

          再次尝试使用 a 作为双精度示例。

          再次尝试您的示例并与浮点数进行比较。

          【讨论】:

            猜你喜欢
            • 2011-12-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-01
            • 2013-08-07
            • 2013-08-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多