2進数の足し算はとても単純です。10進数との違いは 1 + 1 で繰り上がるということだけです。
0 | 1 | |
---|---|---|
0 | 0 | 1 |
1 | 1 | 10 |
コンピュータ内部で整数を何ビットで計算するかは目的により様々ですが、普通32ビットを使い、必要があれば64ビットあるいは128ビットで扱うこともあります。計算結果がこのビット数を越えると正しい答えになりません。
4ビットでは計算結果が 0 以上 15 以下ならば正しい答が出ます。
内部表現 | 符号なし整数 (十進数) |
|||||
---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | ||
+) | 0 | 0 | 0 | 0 | 0 | |
加算実行 | 計算値 | 正しい値 |
内部表現のビットをクリックして数値を設定し、[加算実行]で和を求めます。
もう少し大きな数を扱いたいときは8ビットを見てください。
結果の表です。
コンピュータの 内部表現 |
計算値 | 正しい値 |
---|---|---|
0000 | 0 | 0 |
0001 | 1 | 1 |
0010 | 2 | 2 |
0011 | 3 | 3 |
0100 | 4 | 4 |
0101 | 5 | 5 |
0110 | 6 | 6 |
0111 | 7 | 7 |
1000 | 8 | 8 |
1001 | 9 | 9 |
1010 | 10 | 10 |
1011 | 11 | 11 |
1100 | 12 | 12 |
1101 | 13 | 13 |
1110 | 14 | 14 |
1111 | 15 | 15 |
10000 | 0 | 16 |
10001 | 1 | 17 |
10010 | 2 | 18 |
10011 | 3 | 19 |
10100 | 4 | 20 |
10101 | 5 | 21 |
10110 | 6 | 22 |
10111 | 7 | 23 |
11000 | 8 | 24 |
11001 | 9 | 25 |
11010 | 10 | 26 |
11011 | 11 | 27 |
11100 | 12 | 28 |
11101 | 13 | 29 |
11110 | 14 | 30 |
11111 | 15 | 31 |
このgccは unsigned int と宣言すると4バイトの符号なし整数として扱います。32ビットがすべて1である2進数は 4294967295 ですが、代入前に符号つき整数として扱えない数値だと警告されるので、16進数で 0xffffffff と書いています。
0x が16進数を表し、ff が1バイト分の 11111111 を表しています。
#includeint main() { unsigned int a = 0xffffffff; unsigned int b = a + a; printf("%u\n",a); printf("%u\n",a+1); printf("%u\n",a+2); printf("%u\n",a+3); printf("%u\n",b); return 0; }
実行結果
adachi@dirac:~/c$ gcc unsignedtest.c -o unsignedtest adachi@dirac:~/c$ ./unsignedtest 4294967295 0 1 2 4294967294
4294967295 が符号なし整数の限界ですから、それに1を足すと 0 になってしまいます。
これは4ビットの符号なし整数の限界が 15 でそれに1を足すと 0 になってしまうのと同じです。
実際のプログラムではこのようなことがないように対策をたてます。
上記のリテラルの扱い(代入前に符号つき整数に対する)についての警告は以下のようなもの。
unsignedtest.c:4: warning: this decimal constant is unsigned only in ISO C90聖愛中学高等学校