【问题标题】:why there is a different types of output for different float comparisons为什么不同的浮点比较有不同类型的输出
【发布时间】:2014-12-05 04:33:38
【问题描述】:

我有以下代码
案例1

float a=1.7;
    if(a==1.7)
    {
        printf("Equal\n");
    }
    else if(a<1.7)
    {
        printf("less\n");
    }
    else{
        printf("Greater\n");
    }

输出

Greater

案例 2

float a=1.3;
if(a==1.3)
{
    printf("Equal\n");
}
else if(a<1.3)
{
    printf("less\n");
}
else{
    printf("Greater\n");
}

输出

Less

为什么输出不符合预期?
为什么两种情况下的输出不同?
谁能在这里解释这些值是如何存储和比较的
提前致谢

【问题讨论】:

  • afloat,1.7 是 double。由于分配到最接近的 FP 值,1.7 到 float 和 1.7 到 double,它们不同。
  • 当您编写 a=1.3 时,它并不完全存储 1.3。可以是 1.3000000001 也可以是 1.29999999。这取决于编译器。因此,要检查两个浮点数是否相等,您必须使用 fabs()。你可以这样写 if(fabs(a-1.3)
  • 阅读floating-point-gui.de 很好地解释了这一切。

标签: c


【解决方案1】:

事物的组合 -

  • C 内部使用双精度; float 是一种存储格式。

  • 以二进制表示时,1.3 是无限重复的十进制

  • IEEE 浮点在存储尾数时对其进行舍入。 1.3 存储为浮点数 向下取整,1.7 向上取整(一点点)

  • 读取时的浮点数将通过添加额外的数字转换为双精度数 最低有效位设置为 0。向下舍入的值小于它们 是。被四舍五入的值,即使以全零结尾,也更大。

  • 当比较 1.xyzxyz000000 和 1.xyzxyzxyzxyz 时,不是所有的 xyz 都是 0, 以零结尾的会更少。

编辑:之前错过了 ieee 舍入方面

出于好奇,这里是 1.3 和 1.7 存储为 32 位浮点数的实际值:
1.299999952316284179687500000000
1.700000047683715820312500000000

作为 64 位浮点数:
1.300000000000000004440892098500626161694526672363281250000000000000000
1.69999999999999995559107901499373838305473327636718750000000000000000

【讨论】:

    【解决方案2】:

    当您为float 分配一个文字,然后将结果与相同的文字进行比较时,您应该看到值相等。问题是,在您的代码中,您没有将floatfloat 进行比较:这是floatdouble 的比较。

    常量1.71.3 的类型为double。当您将它们与 float 进行比较时,float 的值会在比较之前扩展为 double。这是值变得不相等的阶段:除非常量被准确表示(1.71.3 都不能准确表示为浮点数),否则将出现转换错误。

    您可以通过与 float 常量进行比较来解决此问题:如果您在比较之前将常量转换为 float,则相等性检查将成功:

    float a=1.7;
    if(a==(float)1.7) {
        printf("Equal\n");
    } else if(a<(float)1.7) {
        printf("less\n");
    } else {
        printf("Greater\n");
    }
    

    Demo(打印Equals)。

    【讨论】:

      【解决方案3】:

      在检查情况下,它将考虑一个整数。所以它会将浮点值四舍五入为 整数。

      1.7  roundup as 2. 
      1.3  roundup as 1.
      

      所以这就是这个答案的原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-24
        • 2017-06-01
        • 1970-01-01
        • 2012-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-10
        相关资源
        最近更新 更多