負の数と浮動小数の表現
-5 を 10000101と表示してみます。5 と -5 を単順に加算しても、
00000101 + 10000101 = 10001010となり、0 になりません。そこで、2の補数を利用します。同じ桁数 b の範囲で n に加算したら 0 になる数を2の補数(以後単に補数)とよび、 n の負の数とします。n の補数は、n の2進表記の各桁の0と1を反転し 1を加えます。この補数と n を加えると、下 b 桁は 0 になります。
0000 0101 + 1111 1011 ------------ 10000 0000どうように、1111 1011 の補数は 0000 0100 +1 ですから 10進数で 5 になります。負の数として補数を利用することで、符号に関係なくそのまま加えることができます。また、減算 A - B は、A +(Bの補数) となり補数を求めることで、補数と加算で減算ができます。補数を求めることは減算より簡単です。負の数の最上位ビットは1になりますから、最上位ビット(下図 S)を符号ビットと呼ぶます。
//補数と整数の内部表現 #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { int num=20; int i; unsigned char *p; printf("10進数:%d,%d\n",num,-num); printf("16進数:%08x,%x\n",num,-num); //先頭番地から順に表示する printf("16進数:"); p = (unsigned char *)#//numの先頭番地をpに for (i=0; i<sizeof(num); i++) { printf("%02x ", *(p)); p++;//次の番地 } printf("\n"); return 0; } //結果 //10進数:20,-20 //16進数:00000014,ffffffec //16進数:14 00 00 00int は4バイトで構成されますが、下位のバイトから順にメモリに配置されます。この記憶形式をリトルエンディアンといいます。上位バイトを先頭に配置するビッグエンディアン方式を採用しているコンピュータもあります。
//2のべき乗の計算 #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { int p=1,i; printf("べき乗 10進数 16進数\n"); for(i=1;i<32;i++){ p = p * 2; printf("%2d: %12d ,%8x\n",i,p,p); } return 0; } 結果 べき乗 10進数 16進数 1: 2 , 2 2: 4 , 4 3: 8 , 8 8: 256 , 100 9: 512 , 200 10: 1024 , 400 28: 268435456 ,10000000 29: 536870912 ,20000000 30: 1073741824 ,40000000 31: -2147483648 ,80000000
0 1000 0111 011 0110 1010 0000 0000 0000 s=0 e=10000111 m=011 0110 1010 0000 0000 0000では、e = 10000111 となりこれは 01111111 より 8 だけ大きな数ですから、10進数で E= 8 になります。s=0 ですから、この数は
0100 0011 1011 0110 1010 0000 0000 0000 = 0x43 B6 A0 00になります。次のプログラムで、確認ができます。少数も先頭バイトが最後に配置されます。