C 程序输出具有不同数字的不同值

C program outputting different values with different numbers?

本文关键字:数字 程序 输出      更新时间:2023-10-16

请参阅下面的程序

#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");
}

还有另一个程序在这里

#include<stdio.h>
    int main()
    {
        float x = 0.5;
        if (x == 0.5)
            printf("IF");
        else if (x == 0.5f)
            printf("ELSE IF");
        else
            printf("ELSE");
    }

从这两个程序中,我们期望获得相似的结果,因为两个程序都没有发生任何变化,一切都相同,并且比较术语也相应更改。

但是上述 2 个程序会产生不同的结果

第一期节目

ELSE

第二期课程

IF

为什么这两个程序的行为不同

这两个程序的行为因计算机和操作系统而异 - 您正在测试floats完全相等性。

在内存中,floatsbinary存储为一串位 - 即二进制 (0.1b) 中的 0.1 表示十进制 (0.5d) 中的 0.5。

同样地

Binary | Decimal
0.1    |  2^-1        = 1/2
0.01   |  2^-2        = 1/4
0.001  |  2^-3        = 1/8
0.11   |  2^-1 + 2^-2 = 3/4

问题是一些小数没有很好的浮点表示。 0.1d = 0.0001100110011001100110011...这是无限长的。

所以,0.5 在二进制中真的很好

0.5d = 0.1000000000000000...b

但是0.1真的很讨厌

0.1d = 0.00011001100110011...

现在,根据您的编译器,它可能假设 0.1f 是一种double类型,它存储了更多 0.000110011001100110011001100110011001100110011...因此,它不等于float版本,后者更早地截断了序列。

另一方面,无论存储多少位小数,0.5f 都是相同的,因为它在第一位之后全是零。

在C++或C中比较float s或double s的公认方法是#define一个非常小的数字(我喜欢称之为EPS,EPSILON的缩写)并替换

float a = 0.1f
if (a == 0.1f) {
    printf("IFn")
} else {
    printf("ELSEn")
}

#include <math.h>
#define EPS 0.0000001f
float a = 0.1f
if (abs(a - 0.1f) < EPS) {
    printf("IFn")
} else {
    printf("ELSEn")
}

实际上,这测试的是 a 是否"足够接近"0.1f 而不是完全相等。对于 99% 的应用程序,这种方法工作得很好,但对于超灵敏计算,需要一些更奇怪的技巧,涉及使用 long double 或定义自定义数据类型。

您正在使用两种数据类型:双精度,自动在if(x=0.1)

)(0.1 是双精度)和 x 是浮点数。 这些类型存储值的方式不同。 0.1 不是 0.1f,它是 0.100000000001(双精度)或 0.09388383(某物)