質問: 2の補数形式において、アンダーフローなしに10010110から引くことのできる最大の値を10進表記で答えなさい どうすればいいでしょうか? 2の補数形で11101001 正しいですか? またアンダーフローとオーバーフロー符号付き符号なしにどう違いますか
回答: 8ビットの2の補数だとして、 10010110は、10進で-106(反転して01101001 1を足す01101010 = 0x6A = 16*6 + 10 = 106 に符号を付けて-106)で 8ビットの2の補数で表現できる一番小さい数が-128 なので、(-106 - 22 = -128) 10進で22です。 Cでの問題ではないように思いますが、 C(gcc)で検証プログラムを書くと、 ``` #include int main(void) { signed char v = 0b10010110, min = 0b10000000; printf("%d %d %d\n", v, min, min - v); } ``` 結果:`-106 -128 -22` 8ビットの2の補数形式で表現できる数は -128~127です。 アンダーフローとは演算の結果が-128未満になって(-128~127の範囲で)表現ができなくなることで、 オーバーフローとは演算の結果が128以上になって表現ができなくなることです。 8ビット符号無しの数の場合表現できる数の範囲は 0~255です。 別の検証プログラム ``` #include #include #include #include int main(void) { int8_t v = strtol("10010110", NULL, 2); int8_t i; for(i = 1; INT8_MIN + i < v; ++i) ; printf("Ans.%" PRId8 "\n", i); } ``` 結果:`Ans.22` 2進数演算で ``` 10000000 -10010110 ``` 足し算にする。 ``` 10000000 +01101010 11101010 ``` 反転して `00010101` +1する `00010110` 22(16+4+2)