まず、質問の性質と、実装に依存しないオーバーフローラッピングに関する公式の(私が知っている)標準がないため、答えは正式には*不確定*です。
とは言うものの、非公式にそれの地獄のためにいくつかの数字をクランチさせましょう。これを32ビットint
で計算しますが、64ビットの数値ははるかに印象的です。3
2^32も2^64も均等に割り切れないため、増分としての選択は非常に有利です(おそらく設計によるものですか?)。これにより、オーバーフローの連続性に最適になります。
物事を簡単にするいくつかのキー番号:
2147483646 := (715827882 * 3)
-2147483647 := (2147483646 + 3) with overflow
Y = 0、X = 0であるため、反復ステートメントは実行されません。
- Y = 1、X = 0,3,6,9 ... 715827882の増分後、2147483646。次の増分はオーバーフローし、X=-2147483647になります。別の715827882は後で増分し、X=-1です。正の領域とX=2に戻るためのもう1つの増分。全体をもう一度繰り返し、X = 1、合計4 * 715827882 + 3、合計= 2863311531。
- Y = 2、X = 0,3,6,9 ....上記の(1)を思い出してください。2*(715827882 + 1)の増分で、2、つまり1つのフルパスに到達しました。したがって、別の1431655766の実行、合計= 4294967297
- Y = 3、明らかな理由で、1回の反復でY = X=3。合計= 4294967298
- Y = 4、(1)を繰り返しますが、もう1つ増分を追加します。したがって、4 * 715827882 + 3 + 1回の反復、または2863311533。sum= 7158278830
- Y = 5、(2)を繰り返しますが、もう1つ増分を追加します。したがって、2 *(715827882 + 1)+ 1回の反復、または1431655767、合計= 8589934597
- Y = 6、(3)を繰り返しますが、もう1つ増分を追加します。したがって、1 + 1回の反復、合計= 8589934599
- Y = 7、(4)を繰り返しますが、もう1つ増分を追加します。したがって、4 * 715827882 + 3 + 1 + 1回の反復、または2863311533。sum= 11453246132
- Y = 8、(5)を繰り返しますが、もう1つ増分を追加します。したがって、2 *(715827882 + 1 + 1)+ 1回の反復、または1431655768、合計= 12884901900
- Y = 9、(6)を繰り返しますが、もう1つ増分を追加します。したがって、1 + 1 + 1回の反復、合計= 12884901903
1秒あたり3億回の反復をスピンできると仮定すると、完了するまでに約42.95秒かかります。
64ビット計算は思考の糧として残しておきます。ただし、実際の数値を熟考するために、64ビット整数空間での(val + = 3)インクリメントには、6148914691236517206の反復が必要です。上記の手順の中には、2回、1回、まったく実行しないものがあります。
32ビットのsignedint値を使用するようにテストプログラムを変更しました。
#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