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。

因为1int ,32位,所以(1 << 27)*27溢出。 使用1ull

关于你的注释,如果xuint64_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); } 

尚未编译