C左移64位失败
我在C中有这个代码(仅供学习):
char x; uint64_t total = 0; for(x = 20; x < 30; x++){ total = (((((1 << x) * x) / 64) + 1) * sizeof(uint64_t)); printf("%d - %llu\n", x, total); }
什么是印刷品:
20 - 2621448 21 - 5505032 22 - 11534344 23 - 24117256 24 - 50331656 25 - 104857608 26 - 218103816 27 - 18446744073625665544 28 - 18446744073575333896 29 - 18446744073508225032
为什么在x> 26时我有那些奇怪的值? 我在Ubuntu 10.10 64位上的gcc 4.6.1。
因为1
是int
,32位,所以(1 << 27)*27
溢出。 使用1ull
。
关于你的注释,如果x
是uint64_t
,那么1 << x
仍然是一个int
,但是对于乘法它将被转换为uint64_t
,所以没有溢出。 但是,如果x >= 31
1 << x
将是未定义的行为(因为结果值不能用带符号的32位整数类型表示)。
我猜您的问题是,您使用32位计算并稍后将其分配给64位值
除以64与64位相同
char x; uint64_t one = 1; uint64_t total = 0; for(x = 20; x < 30; x++){ total = ((((one << (x - 6)) * x) + 1) * sizeof(uint64_t)); printf("%d - %llu\n", x, total); }
尚未编译