▲2進数専用そろばん |
前回の章では2進数について学んできました。2進数は0と1でしか表せません。
では、10進数でマイナスの場合は2進数ではどうなるの?また、10進数での小数点以下のの場合はどうなるの?といった疑問があると思います。当然、2進数は0と1(ONとOFF)しかありませんので、符号や小数点といったことは出来ません。と言いたいところですが、10進数でのマイナス(負数)や小数点の場合の2進数の表し方があります。
ここでは、負数(補数)・小数の表し方について説明していきます。
まず「補数」という言葉をご存じでしょうか?
みなさんがよく利用しているwikipedia(ウィキペディア)では
「補数(ほすう;complement)とは、ある基数法において、ある自然数 a に足したとき桁が1つ上がる(桁が1つ増える)数のうち最も小さい数をいう。」
となっています。例えば10進数で55の補数は、桁の繰り上げは100なので、
100−55=45
で補数は45になります。
この補数を使って、10進数の引き算を計算する場合、、例として8−7を計算してみましょう。
8−7 は 8+(−7)ですよね。
ここで補数を使って計算する場合、1つルールを設けます。桁上がりした数字は無視てください。
7の補数は10−7ですので、3です。
補数を使って計算すると、
8+3=11ですが、先ほどの桁上がりした数字は無視するルールにすると、答は「1」です。
ちょっとややこしいですが、2進数の内部ではこの方法で計算を行っています。
2進数で負の数を表現する時は、先ほどの補数の技術を使います。
2進数の負数(補数の求め方は一番頭のビットを1にし、すべてのビットを反転させ1ビットを追加します。
例えば、10進数で125を2進数に変換すると、01111101となります。
10進数で−125を表現する場合、まずは頭を1ビットにして、すべてのビットを反転させますので10000010となります。それに1ビット追加するので、
答えは10000011となります。
なぜ、負数はこんな厄介な表わし方になるのかというのには理由があります。
中央演算装置は電気信号で行っているため、「引き算」が出来ません。引き算も「足し算」で行っています。なぜ「引き算」ができないかというのは後の「論理演算」の章で詳しく説明いたします。
普通126−125=1と簡単に求めることが出来そうですが、中央演算装置の内部では126+(−125)というように変換し、足し算で「引き算」を行っています。
10進数で126は進数では01111110です。126−125を行う場合、中央演算装置内では011111110+10000011としています。その答えが00000001となります。
10進数の整数を2進数に変換する方法は前章で説明しました。今回は10進数の小数を2進数に変換する方法を説明します。
10進数の小数部分を2進数に変換する場合は小数部分に2を掛け、整数部分が1の場合は2進数で「1」整数部分が0の場合は「0」にします。そして、整数部分を取り除き、小数部分だけ再度2を掛けて繰り返します。
例えば10進数で「0.625」を計算します。
0.625×2=1.25 整数部分は「1」なので、2進数の小数部分の最初のビットは「1」です。
1.25の小数部分は0.25ですので、
0.25X2=0.5 整数部分は「0」なので、2進数の小数部分の2つ目のビットは「0」です。
0.5X2=1.0 整数部分は「1」なので、2進数の小数部分の3つ目のビットは「1」です。
よって0.625は2進数で0.101となります。
同じようにして10進数の「0.4」の2進数を求めてみましょう。
0.4×2=0.8 整数部分は「0」なので、2進数の小数部分の最初のビットは「0」です。
0.8X2=1.6 整数部分は「1」なので、2進数の小数部分の2つ目のビットは「1」です。
0.6X2=1.2 整数部分は「1」なので、2進数の小数部分の3つ目のビットは「1」です。
0.2X2=0.4 整数部分は「0」なので、2進数の小数部分の4つ目のビットは「0」です。
0.4X2=0.8 整数部分は「0」なので、2進数の小数部分の5つ目のビットは「0」です。
0.8X2=1.6 整数部分は「1」なので、2進数の小数部分の6つ目のビットは「1」です。
0.6X2=1.2 整数部分は「1」なので、2進数の小数部分の7つ目のビットは「1」です。
0.2X2=0.4 整数部分は「0」なので、2進数の小数部分の8つ目のビットは「0」です。
0.4X2=0.8 整数部分は「0」なので、2進数の小数部分の9つ目のビットは「0」です。
ちょっとここで疲れてきましたね。同じことを繰り返していて終わりがなくなってきました。
10進数で0.4の2進数は「0.0110011001100・・・・・」となってしまいます。このような形式を「循環小数」といいます。
10進数の表記で循環小数でなくても、2進数の変換すると循環小数になるものもあります。この現象については、プログラム上でもよくある現象です。
例えばエクセルなどで「浮動小数点」の形式で小数の数値を保存した場合、再度開くと数値が変わっている場合があります。0.3で保存したのに、再度開くと「0.29999999」になっていたりします。
また、プログラムを作っているときに、変数を浮動小数点にして変数に「0.3」を代入すると、結果が「0.30000000000000004」と出たり、「0.2+0.1」の結果を代入すると「0.29999999999999999」となったりします。
では、なぜ「0.3」という数値を出しているのかというと、2進数を10進数に変換してから小数部分の丸め込みを行っており、「0.3」と出しています。
プログラムを作成する場合、小数点を計算する場合、「切り上げ」、「切り捨て」、「四捨五入」というルールを明確にしなければ誤差が出ますので注意してください。
|
|
|
否定論理積は論理積(AND)を否定します。したがって「条件にどちらも当てはまることがない」ときに「真」を出力します。
|
否定論理和は論理和(OR)を否定します。したがって「条件にどちらか当てはまることがない」ときに「真」を出力します。
|
排他的論理和は論理和(OR)の排他的な値のみが「真」となります。したがって両方の条件が当てはまるときは「偽」、片方の条件だけが当てはまるときだけ「真」を出力します。
|
これを使って、次章では実際に2進数の計算の仕組みを説明していきます。
まずは、1桁目の位だけで考えていきます。
2進数の加算は
0+0=0
0+1=1
1+0=1
1+1=10(下の桁0)
ですね。この法則、どこかで見かけませんでしたか?排他的論理和(XOR)の真偽値表と同じですよね。下の位は排他的論理和で計算を行っていることが分かります。
次に、桁上がりを考えましょう。
0+0=桁上がりなし(0)
0+1=桁上がりなし(0)
1+0=桁上がりなし(0)
1+1=桁上がりあり(1)
となります。この法則は論理積(AND)と同じ法則です。桁上がりの動作は論理積(AND)で行っています。
ビットA | ビットB | a+bの値 | 上位への桁上がり |
0 | 0 | 0 | 0 |
0 | 1 | 1 | 0 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 1 |
A | B | AとBのXOR | AとBのAND |
以上から、2進数の計算は排他的論理和(XOR)と論理積(AND)の合体で行っていることが分かりました。回路図は下図のようになります。
1桁目はいいけど、桁上がった2桁目の計算はどうすうるの?という疑問がふと生まれましたよね。上の回路は下の位からの桁上がりを無視した回路です。この回路を「半加算回路」といいます。
では、桁上がりを考慮した回路はどうなのでしょうか?
下の表から考えてみましょう。
ビットA | ビットB | 下位からの桁上り値 | a+b+cの値 | 上位への桁上がり |
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 | 0 |
0 | 1 | 0 | 1 | 0 |
0 | 1 | 1 | 0 | 1 |
1 | 0 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 1 |
1 | 1 | 0 | 0 | 1 |
1 | 1 | 1 | 1 | 1 |
一見ややこしくなりますが、先ほどの「半加算回路」で下位の計算をXORで行っているということで、「ビットA」と「ビットB」の部分を論理演算の「XOR」に変えると下の表になります。
ビットAとBのXOR | 下位からの桁上り値 | a+b+cの値 |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
1 | 0 | 1 |
1 | 1 | 0 |
0 | 0 | 0 |
0 | 1 | 1 |
A | B | AとBのXOR |
上の表で「XOR」と「下位からの桁上がりの値」の演算結果が「a+b+cの値」として見た場合、ここも排他的論理和(XOR)になっているのに気付きましたか?排他的論理和(XOR)が2個使用していることが分かりました。
では桁上がりの部分はどうなっているのでしょうか?「半加算回路」では桁上がりは論理積(AND)で行っていると言いましたよね。
そこで、「ビットAとビットB」の論理積(AND)、「ビットAと下位からの桁上がり値」の論理積(AND)、「ビットBと下位からの桁上がり値」の論理積(AND)を作って見ましょう。
なぜこの3つの論理積を求めるかというと、パターンによって桁上がりが異なるため、この3つのパターンをまず作って見てください。そうすると下の表になります。
ビットAとBのAND | ビットAと桁上がりのAND | ビットBと桁上がりのAND | 上位への桁上がり |
0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 |
0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 |
1 | 0 | 0 | 1 |
1 | 1 | 1 | 1 |
A | B | C | AとBとCのOR |
この3つの結果を論理和(OR)にすると、「上位の桁上がり」に一致しましたよね。これを回路図にすると下図のようになります。
つまり、デジタルの世界では最初の1桁は「半加算回路」で、2桁目以降は「全加算回路」で計算を行っています。