8

我在 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。

4

2 回答 2

23

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

关于您的评论,如果x是 a uint64_t,那么1 << x仍然是 a int,但是对于乘法,它将被转换为uint64_t,因此不会溢出。但是,如果x >= 31,1 << x将是未定义的行为(因为结果值不能由带符号的 32 位整数类型表示)。

于 2012-04-06T19:10:50.247 回答
0

我猜你的问题是,你用 32 位计算,然后将其分配给 64 位值

除以 64 与不移位 6 位相同

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);        
}

还没编译

于 2012-04-06T19:11:51.473 回答