アーカイブ

2008 年 12 月 のアーカイブ

2進数とは 〜0より小さい数を0と1で表す?〜

2008 年 12 月 9 日

いよいよ2進数の山場です。

やっぱり、マイナスの値(負数)を表現できないと、計算ではこまりますよね。

普段私たちは「ー」という記号を使って表現します。

5のマイナス値はー5となります。

2進数でも「ー」という記号を使って負数を表現することはできます。

例えば10b(2進数の10と言う意味です)であれば、ー10bとすればよいのです。

ところが、コンピュータは0と1しか使えないという制限があるため、「ー」という記号を追加することができないのです。

こんなにもコンピュータと言うのは融通が利かないのかと腹を立てる人もいるかも知れませんが、どうしようもありません。

では、0と1だけで”どうやって”負数を表すのか? 実はトリックがあるのです。

10進数の世界では、44に56を加えると100になります。

この時、「私たちは2桁の数字までしか考えない」と宣言すれば、100のうち2桁の数字は「00」つまり0となります。

「正の数字同士を足したのに0になる」

これがトリックです。

44は正の数ですが、56は実はー44と考えるのです。

編に深く考えないでください。ー44を数字だけで表現すると56となると決めただけです。

では、なぜ56か?

先ほどの足し算の式を入れ替えると、

100ー44=56

となります。これがトリックの中身です。

100は「0」としたのですから、上の式は次のように表すことができます。

0ー44=56

56は44より大きい数なのに、ー44と同じ意味になるというトリック。

ある基準の数字(この場合は100)からどれだけ足りないかという表現方法を「補数」といいます。

つまり、44の100の補数は56なのです。

納得出来ないですか?

数字遊びと同じです。そのように「扱う」と遊びのルールを決めただけのことです。

トランプゲームのブラックジャックのように、Aを1か11として扱えるルールみたいなものです。

ただし、補数にはもう1つのルールがあります。

扱える数字の範囲が制限されるのです。

100を基準に考えると、正の数50種類と負の数50種類の計100通りが扱えることになり、
ー50〜+49までの数字(0を含めて100通り)しか使えません。
負数の補数表現の表をご覧ください。

表現したい数字 表現したい数字 補数表現
-1 99
-2 98
-3 97
-4 96
-5 95
-6 94
-7 93
-8 92
-9 91
-10 90
-20 80
-30 70
-40 60
-50 50

この様に、ー1〜ー50までの50通りを50〜99で表現し、0〜49までの50通りを0〜49(そのまま)で表現するのです。

「99」はー1となるという考えは、皆さんの生活では扱いにくいかもしれませんが、

コンピュータによってはとても助かるのです。

「引き算」という考えを捨てることができるからです。

ー1+10と言う式は、補数表現では99+10となります。

結果は109ですが、下2桁しか取りませんから、9となり計算はあっています。

ー50〜+49までの範囲内というルールの中では、引き算は不要となるのです。

ただし、掛け算は注意が必要です。20x20という式は、それぞれ範囲内ですが、

計算結果の400は範囲外ですから、計算できないことになります。

これもルールです。では、実際のコンピュータはどうしてるかって?

基準となる数字が十分大きければ問題ないのです。

最近のコンピュータは32ビットが基本ですから、基準となる数字は232乗つまり4,294,964,296を基準にします。

すると、-2,147,483,648〜+2,147,483,647までの数字が扱えるのです。

約21億まで扱えれば、普通の計算であれば問題ないはずですよね。

まだ足りない?

そんな時は、64ビットで計算するのです。CPUは32ビットでも、64ビットで計算できるのです。

ちなみに、64ビットでは18,446,744,073,709,551,616を基準にしますので、

ー9,223,372,036,854,775,808〜+9,223,372,036,854,775,807までの数字が扱えます。

これなら足りるでしょ?

という途方もない数字の後に恐縮ですが、コンピュータが扱う2進数で表すとどうなるのでしょうか?

1バイト(8ビット)を基準に考えてみます。

8ビットは2の8乗ですから、256種類、ー128〜+127までの数字が扱えることとなります。
2進数でのこのルールを「2の補数」表現と呼びます。

10進数の数字 256の補数 2の補数表現
-1 255 11111111
-2 254 11111110
-3 253 11111101
-4 252 11111100
-5 251 11111011
-6 250 11111010
-7 249 11111001
-8 248 11111000
-9 247 11110111
-10 246 1110110
-127 129 10000001
-128 128 10000000

この様に、2の補数表現を用いることで0と1だけでも負の数を表すことができるのです。

ただし、ここで注意が必要です。11111111bとだけ書かれている場合に、「ー1」なのか「+255」

なのかは、判別できないということです。

したがって、2の補数表現なのか、絶対値表現(常に正の数)なのかはあらかじめルールとして

決めておく必要があります。

ここが重要ですので、よく覚えておいてください。

2の補数表現で記載した負の数を見ると、1つ特徴があります。

一番上位のビットが必ず1なのです。

よって、2の補数表現の数字は、見た目で負数か正数かが判断できて、便利です。

今日はここまで。

(参考)

2の補数表現では、一番上位のビットが1か0かで正負が分かりました。

それなら、上位1ビットを符号ビット(正負)として考えれば、

わざわざ256から引かなくても良いのではないかと考える方もいらっしゃるでしょう。

その通りです。

ルールとして、上位1ビットを符号ビットとして、以下7ビットは絶対値として書けば、

-127〜+127まで表現できます。この方が人にはわかりやすいです。

ー1は10000001bとなります。

ー127は11111111bとなります。

この表現方法を「1の補数」表現と呼びます。

非常にわかりやすいですね。

ですが、コンピュータにとっては面倒なのです。

まず、-0と+0が存在してしまいます。

つまり00000000bと10000000bです。

そして、計算する時には先頭の1ビットを見て、足し算か引き算かを判断し、計算しなければなりません。

2の補数表現では、何も考えずに足し算すれば計算できます。

1の補数表現は計算の手順が増え面倒なのです。

こんな理由から、現在のコンピュータでは負数を表現するのに、2の補数を用います。

ただし、本日の重要ポイントのとおり、2進数の数を絶対値(正の数のみ)で扱うか、2の補数表現で

扱うかは、使う人(つまりあなた)の自由ですよ。

admin プログラミング講座

2進数とは 〜10進数との関係〜

2008 年 12 月 9 日

2進数とは0と1で出来ていることは、ここまでの講義を受講された方はお分かりのことだと思います。

そろそろコンピュータ寄りの内容にしていきましょう。

いきなり結論ですが、現在一般的に使用しているコンピュータは0と1しか使えません。

究極な2進論者です。

じゃあ、文字や画像や数字の「ー」はどうするんだ?という疑問が出てくれば、筆者は嬉しいです。

「それでもコンピュータは0と1しか使えない」

ガリレオの名ゼリフのようにはいきませんが、これは絶対の制限なのです。

しっかりと覚えておいてください。

そろそろ本題です。

電卓もコンピュータです。しかも0と1しか使えません。

しかし、10進数の計算をすることができます。

実は2進数と10進数はお互いに変換することができます。(一部を除いては・・・)

この作業を基数変換と言います。

ますは、2進数から10進数の変換。

ある2進数の数字を1101bとします。

bとは、2進数の数字であると、わかりやすくするための記号です。コンピュータの中では使用されません。

あくまで、人が10進数と間違えないようにする記号です。

先ほどの数字を10進数に変換します。

  1. 1桁目に1を掛けます。
  2. 2桁目に2を掛けます。
  3. 3桁目に4を掛けます。
  4. 4桁目に8を掛けます。
  5. 上4つの計算で出た数字を足します。

これで10進数の数字になります。

つまり、(1x1)+(0x2)+(1x4)+(1x8)=13です。

1011bは13なのです。

4ビットの2進数をすべて10進数にしたものが以下の表です。

  1. 0000b = 0
  2. 0001b = 1
  3. 0010b = 2
  4. 0011b = 3
  5. 0100b = 4
  6. 0101b = 5
  7. 0110b = 6
  8. 0111b = 7
  9. 1000b = 8
  10. 1001b = 9
  11. 1010b = 10
  12. 1011b = 11
  13. 1100b = 12
  14. 1101b = 13
  15. 1110b = 14
  16. 1111b = 15

5ビット以上の2進数はどうやって変換すればよいのでしょうか?

さきほどの変換方法を見ると、1つ桁が増えると2を掛ける数が1つ増えることが分かります。

「n桁目の変換には2の(nー1)乗を掛ける」 (nは1以上の数字)

と言うのが正しいです。

5桁目であれば2の4乗となり、2x2x2x2=16です。

ちなみに0乗は1です。

これだけ覚えておけば、2進数から10進数への変換はできます。

では、10進数から2進数の変換です。

小さな数であれば、上の変換表を見て変換することも出来ますが、大きな数字の場合どうでしょうか?

この様な場合、割り算をして変換を行います。

たとえば、234を2進数に変換してみましょう。

元の10進数の数字を、0になるまでひたすら2で割ります。その時の余りを記録します。

234÷2=117 (余り0)

117÷2= 58 (余り1)

58÷2= 29 (余り0)

29÷2= 14 (余り1)

14÷2=  7 (余り0)

7÷2=  3 (余り1)

3÷2=  1 (余り1)

1÷2=  0 (余り1)

この式の余りの部分をしたから上に書いたもの、つまり11101010が、234の2進数です。

軽く騙されてるような気分ですよね。

では、逆に2進数から10進数に変換し直して、正しいかどうか確認しましょう。

それぞれの桁に2のnー1乗を掛けてすべてを足します。

(0x1)+(1x2)+(0x4)+(1×8)+(0x16)+(1x32)+(1x64)+(1x128)

どうですか?

234になりましたよね?

2進数と10進数の変換はこれで完成です。

何かすっきりしない人は以下を読んでください。

(基数変換の考え)

現在私たちが使う数字は位取り記数法という法則を使っています。

前にお話ししたとおり、ある基数の種類の記号を使って表現し、数があふれると桁を増やす方法です。

10進数であれば、0〜9までの10種類の記号を使い、9の次には1桁増やして10となります。

10種類の記号のことを底と言います。

2進数であれば、0と1を底と呼びます。

そこで、ある数を桁毎に分解してみます。

1234と言う10進数の数字は 1x10 + 2x10 + 3x101 + 4x10 と分解できます。

基数変換とは、使っている記号を変えるだけのことです。

この話の時だけ、2進数の記号を0=○,1=■と置き換えます。(こうしないと、理解しにくいのです)

上の例で使用している数字は、0、1、2、3、4、10です。

これを2進数(AB表記)で表すと、それぞれ○、■、■○、■■、■○○、■○■○となります。

(10進数の10は2進数では1010bですよね? だから■○■○となります)

1x10 + 2x10 + 3x101 + 4x10

は2進数表記にすると以下になります。

■x■○■○■■ + ■○x■○■○■○ + ■■x■○■○ + ■○○x■○■○

■○■○の○乗は、■です。

■○■○の■乗は、■○■○です。

■○■○の■○乗は、■○■○を2乗することですから、計算してみましょう。

■○■○
x■○■○


○○○○
■○■○○
○○○○○○
■○■○○○○


■■○○■○○

よって、■○■○の■○乗は■■○○■○○です。

■○■○の■■乗は、■■○○■○○に、さらに■○■○を掛けたものです。

■■○○■○○
x    ■○■○


○○○○○○○
■■○○■○○○
○○○○○○○○○
■■○○■○○○○○


■■■■■○■○○○

よって、■○■○の■■乗は、■■■■■○■○○○です。

やっと準備が出来ました。これを先ほどの式から計算していきます。

■x■○■○■■ + ■○x■○■○■○ + ■■x■○■○ + ■○○x■○■○

=■x■■■■■○■○○○ + ■○x■■○○■○○ + ■■x■○■○ + ■○○

=■■■■■○■○○○ + ■■○○■○○○ + ■■■■○ + ■○○

=■○○■■○■○○■○

10進数の1234は、2進数では■○○■■○■○○■○となるのです。

0と1にすると、10011010010bです。

この様に、表現する記号を置き換えることが基数変換なのです。

このやり方は、どんな基数への変換でも同じです。

ただ、この方式は計算が面倒なので、実際には使いません。

スッキリしましたか?

admin プログラミング講座