我正在尝试打印 C 中无符号长整型的最大值(在我的机器上为 18446744073709551615),而不使用 limit.h 中的值,也不使用按位运算符(来自 K&R 的练习 2-1,仅使用在预订截止日期)。显然只是作为练习,不适用于任何现实世界的应用。 我的想法(适用于所有其他数据类型)是
printf("Unsigned long: Max: %lu\n", (unsigned long)(pow(2,sizeof(unsigned long)*8)-1));
但由于某种原因,将 (pow(2,64)-1) 的输出转换为 unsigned long 显示为 2^63,即使 unsigned long 足够大以显示 pow(2,64)-1
我已经尝试过了
printf("Unsigned long: Max: %lu\n", ULONG_MAX); // works
printf("Unsigned long: Max: %lu\n", 2*(unsigned long)pow(2,63)-1); // works
printf("Unsigned long: Max: %.0f\n", pow(2,64)-1); // sort of works, but displays 18446744073709551616, i.e., 2^64 instead of 2^64-1
printf("Unsigned long: Max: %lu\n", (unsigned long)(pow(2,sizeof(unsigned long)*8)-1)); // does not work
printf("Unsigned long: Max: %lu\n", (unsigned long)pow(2,64)-1); //does not work
我不明白为什么最后两个选项不起作用。 感谢您的帮助!
获取无符号类型最大值的一个简单方法是使用
-1
:
printf("%lu", (unsigned long)-1);
为什么
(unsigned long)(pow(2,sizeof(unsigned long)*8)-1)
在您的系统上导致 2^63
(我无法在我的系统上重现)的解释可能是您的系统实现 double
类型的方式。你说这是一个 32 位类型,这意味着它不是广泛使用的 IEEE 754 双精度类型。
关于浮点数如何存储,有几个很好的解释,所以我不再重复。参见例如c 中浮点的精确表示。
您的double
类型似乎无法表示 2^64,因此使用值 2^63 作为其最大值或“无穷大”的某种表示(即数字太大而无法表示)。减 1 不会改变该值,因为
double
类型无法表示这样的精度(由于它是 32 位类型,理论上只能表示 2^32 个不同的值,而 64 位 unsigned long 类型可以表示 2^64不同的值)。