我尝试了KR练习2.1 - long
通过直接计算确定变量范围.
#include#include int main() { unsigned short long_bits = sizeof( long ) * CHAR_BIT; printf( "LONG_MAX = %ld\n", ( 1L << ( long_bits - 1 ) ) - 1 ); printf( "LONG_MIN = %ld\n", ( -1 ) * ( 1L << ( long_bits - 1 ) ) ); printf( "ULONG_MAX (1) = %lu\n", ( 1UL << long_bits ) - 1 ); // doesn't work printf( "ULONG_MAX (2) = %lu\n", 2*( 1UL << ( long_bits - 1 ) ) - 1 ); // work printf( "\n" ); }
ULONG_MAX (1) = 0
是错误的,因为我认为左移溢出.
ULONG_MAX (2) = 18446744073709551615
通过用乘以2来替换最后一个左移位似乎是正确的.
所以看起来左移运算符会溢出,但乘法不会?这个中间计算是否会2*( 1UL << ( long_bits - 1 ) )
促进某些类型long
?在我的机器上,long
并且long long
完全相同(8字节).
编辑:正如伦丁指出的那样,所有需要的ULONG_MAX
都是printf( "ULONG_MAX = %lu\n", ~0L );
在这种情况下使用左移导致UB,并且乘以2也可能是UB(尽管情况2的结果看起来是正确的).