• 検索結果がありません。

不思議な計算

ドキュメント内 ( ( 5 10 pdf (ページ 105-108)

10.1.2 2 進数の減算

10.5 不思議な計算

1

10.5.1 突然、負の数が ...

2

表10.2によると、8bitの補数表現で扱うことのできる最大数は12710=011111112です。さて、

3

この数に1を加えると何が起こるでしょうか。「最大数に1を加えてはいけない」と禁止するのも

4

ひとつの考え方ですが、敢えてこの加算を遂行すれば以下の通りです。

5

0 1 1 1 1 1 1 1

+ 1

1 0 0 0 0 0 0 0

6

100000002は表10.2によると、−12810を表しています。つまり、以下の等式が成り立ってしまい ます。

12710+ 110=12810

最大数に1を加えると負の最小数が出てくるのです。同様のことは16 bit /32 bitの補数表現でも 起こります。

3276710+ 110 = 3276810

214748364710+ 110 = 214748364810

2進数(16進数) 10進数 コメント 0 1111...1111| {z }

31

2(= 7FFFFFFF16) 214748364710

... ... 32 bit目が0になることに注目。

0000...0000

| {z }

32

2(= 0000000016) 010 1111...1111

| {z }

32

2(= FFFFFFFF16110

... ... 32 bit目が1になることに注目。

1 0000...0000| {z }

31

2(= 8000000016214748364810

このように、もともと扱える数値の最大値を越えて演算を行う現象を

1

オーバーフロー

(overflow、桁溢れ)と呼んでいます3

2

数をだんだん増やしていくと突然、負の数が現れる訳ですから、これは日常の感覚からすると大

3

変奇妙なことです。もちろん通常の計算でこのようなことが起きては困りますし、大変危険です。

4

プログラマはオーバーフローが起きないように細心の注意を払うべきです4。またオーバーフロー

5

が予想されるときには、 bit幅が大きいデータ表現に変更すべきです。

6

10.5.2 負数どうしの乗算

7

補数表現の加減算では演算数の符号を気にすることなく、あたかも正数どうしのように演算して

8

も構わないことを10.3節において示しました。加減算と同様に、(310)×(410) = 1210などの

9

乗算も、あたかも正数どうしの乗算のように簡単に実現できます。この例を示します。

10

簡単のため8 bitの補数表現を用いるとします。−310の補数表現は111111012です(表10.1参

11

照)。−410の補数表現は111111002です。そこでこの二つの数について、10.1節(c)で述べた方法

12

と同様に、正数どうしの乗算を行ってみます。

13

3逆に-12810から1を引くと12710になりますが、これもオーバーフローです。類語にアンダーフロー(underflow、

下位桁あふれ)があります。興味のある人は自ら調べてください。

4銀行にコツコツと積み立て預金をしていて、あまりに預金額が大きくなったために、突然、預金が借金に変わってしま う...ようなことはあってはなりません。コンピュータの中には、オーバーフローをエラーとして自動的に検知できる機能 を持つものもあります。

1 1 1 1 1 1 0 1

1 1 1 1 1 1 0 1

1 1 1 1 1 1 0 1

1 1 1 1 1 1 0 1

+ 1 1 1 1 1 1 0 1

1 1 1 1 1 0 0 1 0 0 0 0 1 1 0 0

1

なお、8 bit目と9 bit目の境には線を引きました。9 bit目以上を無視するならば、答えは000011002

2

です。これは1210に他なりません。負数どうしの乗算から正数が出てきた訳です。何故このよう

3

な計算が可能なのか、10.7節で理屈を述べます。

4

考察 (310)(410)、(310)(410)を補数表現を用いて計算し、正しく1210が求められること

5

を確認しなさい。

6

10.5.3 補数の簡単な求め方

7

補数を簡単に求める方法を示します。

8

10.3節では1012の8 bitの補数表現を求めるために、2進数1000000002から1012 (厳密には

000001012)を引きました。この操作は、次のようにも変形できます。

1000000002000001012 = (12+ 111111112)000001012

= 111111112000001012+ 12

= (111111112000001012) + 12

上式は、まず111111112から000001012を引き、その後に12を加える、という2段階の操作で補

9

数が求められることを意味します。

10

そこで、前半の引き算を行うと以下の通りです。

11

1 1 1 1 1 1 1 1 ...被減算数

0 0 0 0 0 1 0 1 ...減算数

1 1 1 1 1 0 1 0 ...減算結果

12

この計算の減算数と減算結果の各bitに着目すると、0は1に、1は0に、と数字の反転(bit の

13

反転)の関係にあることに気付きます。

14

0 0 0 0 0 1 0 1  

1 1 1 1 1 0 1 0

15

転を行えばよいのです。

3

このことから、000001012の補数を求める操作とは、000001012の各bitを反転し、その後に12

4

を加える、という操作と考えることができます。単純な bitの反転と12の加算のみです。そのた

5

め、補数は非常に簡単に求めることができるのです。

6

一般化して述べます。nbitの2進数bnbn1...b2b1の補数を求めるには、以下の2段階の操作を

7

行います。

8

bnbn1...b2b1の各bitの0/1を反転し、2進数cncn1...c2c1を求めます。このcncn1...c2c1

9

bnbn1...b2b11の補数(1’s complement)と呼びます。

10

cncn1...c2c1に12を加えます。求められた補数を、1の補数と対比して、特に2の補数(2’s

11

complement)と呼びます。

12

考察  (1) 8 bitの2進数000000002の補数が000000002であることを確認しなさい。(2) 8 bit

13

の2進数000000012の補数が111111112であることを確認しなさい。

14

ドキュメント内 ( ( 5 10 pdf (ページ 105-108)