オーバーフローの様を観測してみる
百聞は一見に如かずシリーズ第二弾
前回int型の変数の値をビット列で表示してみて、負の数が実際に2の補数になっていることを確かめました。
今回はint型の変数がオーバーフローする様を眺めてみましょう
/* 整数をオーバーフローさせてみる */ #include <stdio.h> main() { int x; void displayBits(int); displayBits(2147483647); printf("2147483647 + 1を計算してみる\n"); displayBits(2147483647+1); printf("\n"); displayBits(-2147483648); printf("-2147483648 - 1を計算してみる\n"); displayBits(-2147483648-1); return 0; } void displayBits(int value) { size_t sz = sizeof(int); int c, displayMask = 1 << sz * 8 - 1; printf("%+d = ", value); for (c = 0; c < sz * 8; c++) { putchar(value & displayMask ? '1' : '0'); value <<= 1; if (c % 8 == 7) putchar(' '); } putchar('\n'); }
これを実際に(コンパイル時にwarningが出るけど><)実行してみると
+2147483647 = 01111111 11111111 11111111 11111111 2147483647 + 1を計算してみる -2147483648 = 10000000 00000000 00000000 00000000 -2147483648 = 10000000 00000000 00000000 00000000 -2147483648 - 1を計算してみる +2147483647 = 01111111 11111111 11111111 11111111
2進数としてみると1足したり、1引いたりしているだけなんだけど、先頭の符号を表すビットが反転してしまうために、コンピュータの解釈が真逆になってしまうのですね。*1
百聞は一見に如かず
*1:正確には1引くのではなく、1の2の補数表現(1が32ビット連なったもの)を足しているわけですが