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 更改为整数文字)
双精度数和浮点数可以容纳的位数有限。在您的情况下,值为 9999999999999999
和 1e16
的双数具有相同的 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
).
我正在学习 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 更改为整数文字)
双精度数和浮点数可以容纳的位数有限。在您的情况下,值为 9999999999999999
和 1e16
的双数具有相同的 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
).