浮点数不相等,尽管是相同的?

时间:2014-08-01 14:32:29

标签: c floating-point

以下程序输出This No. is not same。当两个数字相同时,为什么会这样做?

void main() {
    float f = 2.7;

    if(f == 2.7) {
        printf("This No. is same");
    } else {
        printf("This No. is not same");
    }
}

3 个答案:

答案 0 :(得分:7)

  

为什么两个数字相同时都会这样做?

数字不是相同的值。

double可以表示完全通常大约2 64 不同的值。
float可以代表完全通常约2 32 不同的值。

2.7不是其中一个值 - 给定浮点编码的二进制性质与十进制文本2.7

的一些近似值

编译器将2.7转换为最近的可表示double
2.70000000000000017763568394002504646778106689453125
给出double的典型binary64表示。 下一个最好的double
2.699999999999999733546474089962430298328399658203125。
知道超过17位有效数字的精确值会降低实用性。

将值分配给float时,它将成为最接近的可表示float
2.7000000476837158203125。

2.70000000000000017763568394002504646778106689453125不等于2.7000000476837158203125。

如果编译器使用与decimal32/decimal64完全相同的float/double <{1>}的2.7,则代码将作为预期的OP工作。使用基础小数格式的double表示很少见。更常见的是,基础double表示是基数2,编程时需要考虑这些转换工件。

如果代码为float f = 2.5;,则使用二进制或十进制基础格式的floatdouble值会使if (f == 2.5)为真。与高精度double相同的值可表示完全为低精度float

(假设binary32 / binary64浮点)
 double有53位有效位,float有24位。关键是如果作为double的数字的最低有效位(53-24)设置为0,则转换为float,它与floatdouble具有相同的数值。 12.52.7000000476837158203125等数字可以实现这一目标。 (此处忽略范围,次正常和NaN问题。)

这就是为什么精确浮点比较通常仅在特定情况下进行的原因。

答案 1 :(得分:1)

检查此程序:

 #include<stdio.h>
 int main()
{
   float x = 0.1;
    printf("%zu %zu %zu\n", sizeof(x), sizeof(0.1), sizeof(0.1f));
    return 0;
}

输出为4 8 4

除非在结尾指定double (double precision floating point format),否则表达式中使用的值将被视为f。因此表达式“x==0.1″在右侧有一个double和float,它们在左侧以单精度浮点格式存储。

在这种情况下float is promoted to double。 双精度格式使用比单精度格式更多的位用于精度。

在您的情况下,添加2.7f以获得预期结果。

答案 2 :(得分:0)

2.7中的文字f == 2.7已转换为double,这就是2.7不等于f的原因。