c 中的不等式不起作用

Inequalities in c not working

我正在学习 c,我很困惑,因为我的代码似乎将 ( 1e16 - 1 >= 1e16 ) 评估为 true 而它应该为 false。我的代码在下面,它 returns

9999999999999999 INVALIDBIG\n

当我期望它不会 return 任何东西时。我认为使用 long long 可以避免任何大数问题。

int main(void)
{
    long long z;

    z = 9999999999999999;

    if ( z >= 1e16 || z < 0 )
    {
        printf("%lli INVALIDBIG\n",z);
    }
}

1e16 是一个 double 类型的文字值,floats/doubles 对于十进制 arithmetic/comparison 可能不精确(只是许多常见示例之一:十进制 0.2)。它会将 long-long z 向上转换为 double 以进行比较,我猜标准的双精度表示无法存储所需的精度(也许其他人可以演示二进制 mantissa/sign 表示)

尝试将 1e16 更改为 (long double)1e16,然后它不会打印出您的消息。 (更新:或者,正如其他问题评论者所添加的那样,将 1e16 更改为整数文字)

双精度数和浮点数可以容纳的位数有限。在您的情况下,值为 99999999999999991e16 的双数具有相同的 8 个字节的十六进制表示形式。您可以逐字节检查它们:

long long z = 9999999999999999;
double dz1 = z;
double dz2 = 1e16;

/* prints 0 */
printf("memcmp: %d\n", memcmp(&dz1, &dz2, sizeof(double)));

所以,它们是相等的。

较小的整数可以以完美的精度存储在 double 中。例如,参见 Double-precision floating-point format or biggest integer that can be stored in a double

可以精确转换为double的最大整数是253 (9007199254740992).