首先,由于问题的性质以及不依赖于实现的溢出包装的官方(据我所知)标准,答案是正式的 * indeterminable *。
也就是说,非正式地让一些数字只是为了它的地狱。我将为 32bit 计算这个int
,尽管 64bit 的数字更令人印象深刻。选择3
as 增量是非常有利的,(也许是设计使然?)因为 2^32 和 2^64 都不能被它整除,因此非常适合溢出连续性。
一些使事情变得更容易的关键数字:
2147483646 := (715827882 * 3)
-2147483647 := (2147483646 + 3) with overflow
Y=0, X=0 立即,因此不执行迭代语句。
- Y=1, X=0,3,6,9...2147483646 在 715827882 增量后。下一个增量将溢出并且 X=-2147483647。稍后再增加一个 715827882,X=-1。再增加一个增量回到正区域和 X = 2。把整个事情重复一遍,X=1,总共 4*715827882 + 3,sum= 2863311531。
- Y=2, X=0,3,6,9.... 回想一下上面的 (1),它需要 2*(715827882+1) 增量才能达到 2,也就是一次完整的通过。因此又执行了 1431655766 次,总和 = 4294967297
- Y=3,由于显而易见的原因,一次迭代中 Y=X=3。总和= 4294967298
- Y=4,重复(1),但增加一个增量;因此 4*715827882 + 3 + 1 次迭代,或 2863311533。sum= 7158278830
- Y=5,重复(2),但增加一个增量;因此 2*(715827882 + 1) + 1 次迭代,或 1431655767,总和 = 8589934597
- Y=6,重复(3),但增加一个增量;因此 1 + 1 次迭代,总和 = 8589934599
- Y=7,重复(4),但增加一个增量;因此 4*715827882 + 3 + 1 + 1 次迭代,或 2863311533。sum= 11453246132
- Y=8,重复(5),但增加一个增量;因此 2*(715827882 + 1 + 1) + 1 次迭代,或 1431655768,总和 = 12884901900
- Y=9,重复(6),但增加一个增量;因此 1 + 1 + 1 次迭代,总和 = 12884901903
假设您每秒可以旋转 3 亿次迭代,大约需要42.95 秒才能完成。
我将把 64 位计算留作深思。然而,只是为了考虑实际数字,通过 64 位整数空间的 (val+=3) 增量将需要6148914691236517206次迭代,并且上面的某些步骤需要我们执行两次,其他一次,而其他根本不需要。
修改测试程序以确保我们使用 32 位有符号整数值:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
int main(void)
{
int32_t x = 0;
int32_t y = 0;
uint64_t sum = 0;
while (y < 10)
{
x = 0;
while (x != y)
{
x = x + 3; ++sum;
}
printf("x is %d; sum=%" PRId64 "\n", x, sum);
y = y + 1;
}
return 0;
}
输出
x is 0; sum=0
x is 1; sum=2863311531
x is 2; sum=4294967297
x is 3; sum=4294967298
x is 4; sum=7158278830
x is 5; sum=8589934597
x is 6; sum=8589934599
x is 7; sum=11453246132
x is 8; sum=12884901900
x is 9; sum=12884901903