質問: `基本情報処理技術者` 固定長の2進数の足し算を行うと、繰り上がって、桁が増えることがあります。 このような場合、固定長からあふれたビットは切り捨てます。 **→なぜ切り捨てるかわからないです** 参照元URL https://ja.wikipedia.org/wiki/%E3%83%93%E3%83%83%E3%83%88%E6%BC%94%E7%AE%97 **・2進数の足し算** 7+7を下記のように2進数に変えて計算したとき 0111 +0111 ──── 1110→ 0011(+2) **なぜ1110が0011になるのでしょうか?** 参照書籍 うかる!福嶋先生の集中ゼミ基本情報技術者 45P お手数ですがご教授ください。
回答: **以下の回答は多くの部分に推測を含みます。正しい条件等は当該書籍を確認してください。** まず、この問題は4ビットの符号付整数での計算と考えられます。 符号付整数では最上位ビットが1である場合、負数の2の補数表現ととらえます。 これを踏まえて、まず2進数で7+7を計算します。これは ``` 0111 <=7 + 0111 <=7 ──── 1110 ``` となりました。符号なしなら10進数の計算通り「14」と解釈されるところですが、これは符号付整数で、最上位が1になっているため、負数の2の補数表現で解釈しなければなりません。 1110の2の補数、つまりこれと和をとって桁上がりし5ビットになる最小値は ``` 10000 <=5ビット最小値 - 1110 ──── 0010 =>2 ``` 2です。したがって、1110は-2と解釈されます(ここが本のミスか書き写し間違い?)。 正の整数同士の和をとって負数になるのは普通の世界ではありえないのですが、コンピュータの世界ではこのようなことが起こります。これは、「7+7」がこの符号付4ビット整数で表現できる最大値「7」を超えてしまうため起こる現象です。これを**オーバーフロー**と呼びます。 ### 2の補数 そもそも2の補数とかコンピュータの表す数の意味が分かっていないようなのでこの辺にも触れておきます。 まず基本的にコンピュータは加算は得意ですが減算は苦手です。 苦手な減算を得意な加算に置き換え、全体の整合性が取れるように、2の補数表現があるのです。 2だとなじみにくいでしょうから、いつも使っている10進数で考えましょう。 7325-1589を計算しようとすると、繰り下がりが多く一般の人が暗算しようとしても結構面倒です。 では、この引く数1589を、**10000-x**という形で表せたらどうなるでしょう? ``` 7325-1589 = 7325-(10000-x) = 7325-10000+x = (7325+x)-10000 ``` となります。減算の繰り下がりに比べたら加算の繰り上がりのほうが簡単で、 10000引くという計算は簡単なので、そのまま減算するより楽になります。 こういうxを、今は10進数で考えているので、10の補数表現といいます。 4桁で考えた場合、最後の10000引く操作は桁あふれした分を除外することに相当します。 このxを求めると、1589=10000-xですから、**x=10000-1589**となります。 やっぱり繰り下がりのある引き算になるじゃないか...となりそうですが、この計算を ``` x = 10000 -1589 = (9999+1)-1589 = (9999-1589)+1 = 8410 +1 =8411 ``` とします。3行目のカッコ内は10進数で使う最大の数字9が並んだ数からの引き算なので、繰り下がりなく引き算ができます。このカッコの計算で出てきた8410は、1589の**9の補数**というものです。10の補数より1小さいので9の補数というわけです。 これと同じことを2進数でもやるわけです。