2024年09月29日 | 更新 |
2進法は、位取り記数法と呼ばれる、いくつかの数字を並べて数を表現する表現法の一種で、0と1の2種類の数字を使って数字を表現するものを指します。
2進法で表現した数の事を2進数と呼びます。また、2進数は英語でbinary(あるいはbinary number)という事から、2進数の事をバイナリやバイナリーと呼ぶ事もあります。
なお、p進数のp=2の場合も2進数と呼ばれますが、これは、このページで説明している「2進法で表記した数」という意味ではありません。
このため、「2進数」という言葉がどちらの意味で使われているかは、文脈で判断する必要がありますが、コンピューターや論理回路(ディジタル回路)の話の中に「2進数」が出てくる場合は、まず、「2進法表記の数」という意味で使われている(つまり、このページで説明されている)2進数だと考えて、間違いありません。
2進法は、コンピューターなどの論理回路の内部で数を表現する場合に、非常によく使われます。
私たちは普段、10進法で数を表記します。10進法も、2進法と同じく位取り記数法の一種で、0、1、2、3、4、5、6、7、8、および9の、10種類の数字を使って数を表現します。
10進法の場合、0~9の10種類の数字を、何桁か並べる事で、数(負でない整数)を表現します。例えば、5、125、739、6298等は、10進法で表記した数(これを10進数と呼ぶ)の例です。
一方で、2進法の場合は、0と1の2種類の数字を、何桁か並べる事で数を表現します。例えば、0、1、11、101、110101等は、2進法で表記した数(2進数)の例です。
なお、このサイトでは、数が10進法表記であるのか、2進法表記であるのかを分かりやすくするため、10進法表記の場合は、1011の様に、黒い文字で表記しています。2進法表記の場合は、1011の様に、緑色の文字で表記しています。
参考:2進数の1011を、声に出して読むときは、「せんじゅういち」ではなく、「いち れい いち いち」と読みます。
なお、パソコン等でこのサイトをご覧の方は、緑色の2進数にマウスポインタ(マウスカーソル)を合わせると、図1に示す様に、その数を10進法で表記した場合と、16進法で表記した場合の数が表示される様になっています。
参考:このサイトでは、2進数は緑色で表示する事で、10進数でない事を示していますが、色を使えない場合は、10110という2進数を、10110Bの様に、最後にBの文字を追加する事で表したり、(10110)2の様に、括弧で囲んで右下に小さく2を書く事で表したりします。C++やJavaScriptなどのプログラム言語では0b10110の様に、前に0bを付ける事で表したりします。(表記法はプログラム言語により異なります)
この章では、0、1、···と、順に数を数えていく事を考えます。まず10進法で数える場合を考え、次に2進法で数える場合を考えます。
10進法の場合、0、1、···(中略)···、8、9と、9まで数えたら、数字を10種類全部使ってしまいます。その時は、上の桁(10の位)に1を足して、下の桁(1の位)は0に戻します。9という数には10の位はありませんが、こういう場合には、「10の位が0で、その0の表記が省略されている」と考えます。
この様に考えると、9に続いて、10、11、12、···(中略)···、18、19、20、21、···(中略)···、98、99と、99まで数えられます。
99の次は、100の位を1にし、10の位と1の位を0にして、100とします。
そうすると、99の次は、100、101、···と数え続けられます。
100の位までを使い切った時は1000の位を1にして100の位までを0にし、1000の位までを使い切った時は10000の位を1にして1000の位までを0にし···とすれば、いくらでも大きい数まで数え続ける事ができます。
2進法の場合、基本的には10進法と同じように数を数える事ができますが、使う数字が10種類から2種類に減る点が異なります。
まず、0、1と、1まで数えると、0と1の2種類の数字を使い切ってしまいます。
数字を使い切った場合、次の数を数える時は、10進法の場合と同じく、上の桁(10の位)に1を足し、下の桁(1の位)を0にします。1という数字に10の位はありませんが、「10の位が0で、その0の表記が省略されている」と考えます。
そうすると、1に続けて、10、11と、11(10進法だと3)まで数えられます。
11の次は、100の位を1にして、10の位と1の位を0にし、100とします。
こうすると、11の次は、100、101、110、111と、111(10進法だと7)まで数えられます。
111の次は、同様に1000、1001、···と、必要に応じて桁を増やしながら数えていくと、いくらでも大きい数まで数えられます。
前の章で、10進法と、2進法で、数を数える方法について説明しました。
10進法の場合は、0、1、2、3、4、5、6、7、8、9、10、11、12、13、14、15、···と、数を数えていくのでした。
一方で、2進数の場合は、0、1、10、11、100、101、110、111、1000、1001、1010、1011、1100、1101、1110、1111、···と、数を数えていくのでした。
これらの10進数と2進数の数の並びを比較すると、例えば10進数の2は2進数の10に対応し、10進数の3は2進数の11に対応する等といった事が分かります。
この事を言い換えると、10進数の2は2進数の10と同じ数で、10進数の3は2進数の11と同じ数だという事になります。
この様にしてできた、10進数と2進数の対応表を、表1に示します。
10進数 | 2進数 |
---|---|
0 | 0 |
1 | 1 |
2 | 10 |
3 | 11 |
4 | 100 |
5 | 101 |
6 | 110 |
7 | 111 |
8 | 1000 |
9 | 1001 |
10 | 1010 |
11 | 1011 |
12 | 1100 |
13 | 1101 |
14 | 1110 |
15 | 1111 |
この章では、2進数を10進数に変換したり、あるいは逆に、10進数を2進数に変換したりする方法について説明します。
先に示した表1は、10進数と2進数の対応表で、4桁以下の2進数が全部載っています。つまり、4桁以下の2進数ならば、表1を調べる事で、10進数に変換できます。
もっと桁数の多い2進数を10進数に変換したい場合は、もっと大きな対応表を作っておいて、それを調べる事で、理屈の上ではうまくいきます。
ただし、2進数の桁数が多くなると、表のサイズが指数関数的に増えます(とても増えます)から、現実的ではなくなってきます。
例えば、表1の場合の様に4桁までの2進数を網羅するなら、見出し行を除いて24=16行の表になります。これが5桁までなら25=32行、6桁までなら26=64行、···という様に倍々ゲームで増えていき、20桁までの2進数を網羅する表を作ろうとしたら、220=1,048,576行(約百万行)にもなってしまいます。
そこでこの節では、表を使わずに、計算で2進数を10進数に変換する方法を紹介します。
具体的な方法を説明する前に、10進法ではどの様に数を表現しているかを、振り返ってみます。
例えば78429という5桁の数を考えます。この数は、10000の位が7で、1000の位が8で、100の位が4で、10の位が2で、1の位が9になっています。
つまり、78429は7×10000+8×1000+4×100+2×10+9×1という式の計算の結果得られる数を表していると考えられます。この事を、改めて式に書くと、式(1)が得られます。
ここで、10000を104、1000を103、100を102、10を101、1を100と表記する様にすると、式(1)は式(2)の様に書き換える事ができます。
参考:0でない任意の実数xについて、x0=1になります。
話を一般化します。負でない任意の整数iを考え、iがn桁(nは自然数)の10進数で表されるとします。そのn桁の数字が、上の桁から順にan-1、an-2、an-3、···、a1、a0であったとします。(an-1、an-2、an-3、···、a1、a0のいずれも、0~9の範囲の整数) そうすると、式(3)が成立します。
2進数の場合も、同様だと考えられます。
例えば101011という、6桁の2進数を考えます。この数は、1×25+0×24+1×23+0×22+1×21+1×21という式の計算の結果、得られる数を表していると考えられます。これを式で表すと式(4)になります。
25=32、24=16、23=8、22=4、21=2、20=1ですから、式(4)は式(5)の様に書き換えられます
式(5)の右辺を実際に計算すると43になりますから、2進数の101011は、10進数では43になります。
話を一般化します。負でない任意の整数jを考え、jがm桁(mは自然数)の2進数で表されるとします。そのm桁の数字が、上の桁から順にbm-1、bm-2、bm-3、···、b1、b0であったとします。(bm-1、bm-2、bm-3、···、b1、b0のいずれも、0または1) そうすると、式(6)が成立します。
式(6)において、例えば、j=1101の場合について考えてみましょう。1101は4桁の2進数ですから、m=4となります。この事から、式(7)が成り立ちます。
表1を見ても、1101は13に対応している事が分かりますから、2進数が正しく10進数に変換された事が分かります。
式(6)に従って、2進数を10進数に変換するツールを、Syn BASICで作りました。下の画面1で、実際に使う事が出来ます。
ツールを使うには、画面をクリック(またはタップ)して、入力を受け付ける状態にし、10進数に変換したい2進数を入力した後、ENTERキーを押してください。最大で40桁の2進数が入力できます。
下の実行例1は、10110ENTERと入力して、10110という2進数を10進数に変換した例です。22という答えが表示されるだけではなく、1×16 + 0×8 + 1×4 + 1×2 + 0×1 = 22と、計算式も表示されている事が分かります。
入力した2進数を10進数に変換します 10進数に変換したい2進数: 10110 1×16 + 0×8 + 1×4 + 1×2 + 0×1 = 22 2進数の10110は、10進数に変換すると22です。 10進数に変換したい2進数:
参考までに、2進数を10進数に変換するツールのリストを、リスト1に示します。
10 CLS
20 MAX_LEN=40
30 PRINT "入力した2進数を10進数に変換します":PRINT
40 INPUT "10進数に変換したい2進数: ",I$
50 GOSUB *ERRCHK
60 IF ERR<>0 THEN PRINT:GOTO 40
70 GOSUB *DISPRESULT
80 PRINT
90 GOTO 40
100 END
110 *ERRCHK
120 IF I$="" THEN PRINT "数字が入力されていません。もう一度入力してください。":ERR=1:RETURN
130 SUB_LEN=LEN(I$)
140 IF SUB_LEN>MAX_LEN THEN PRINT SUB_LEN;"文字入力されました。";MAX_LEN;"桁以内の2進数を入力してください。":ERR=2:RETURN
150 FOR SUB_I=1 TO SUB_LEN
160 SUB_C$=MID$(I$,SUB_I,1)
170 IF SUB_C$<>"0" AND SUB_C$<>"1" THEN PRINT "0と1以外の文字が入力されました":ERR=3:RETURN
180 NEXT SUB_I
190 ERR=0
200 RETURN
210 *DISPRESULT
220 SUB_LEN=LEN(I$)
230 SUB_RESULT=0
240 FOR SUB_I=0 TO SUB_LEN-1
250 SUB_A=VAL(MID$(I$,SUB_I+1,1))
260 IF SUB_I>0 THEN PRINT " + ";
270 PRINT SUB_A;"×";2^(SUB_LEN-SUB_I-1);
280 SUB_RESULT=SUB_RESULT*2+SUB_A
290 NEXT SUB_I
300 PRINT " = ";SUB_RESULT
310 PRINT "2進数の";I$;"は、10進数に変換すると";SUB_RESULT;"です。"
320 RETURN
0以上の任意の整数jを考え、jがm桁(mは自然数)の2進数で表されるとします。そのm桁の数字が、上の桁から順にbm-1、bm-2、bm-3、···、b1、b0であったとします。(bm-1、bm-2、bm-3、···、b1、b0のいずれも、0または1) この時、式(8)が成立する事は、4-1節でお話ししました。
参考:式(8)は、式(6)と同じ式です。
ここで、2進数の一番下の桁のb0に注目します。b0はjの値により、0または1になります。
実は、b0=0であるための必要十分条件は、jが偶数である事であり、b0=1であるための必要十分条件は、jが奇数である事なのです。
例えば、111010は、一番下の桁が0の2進数ですが、10進数に変換すると58となり、確かに偶数である事が分かります。
また、101011は、一番下の桁が1の2進数ですが、10進数に変換すると43となり、確かに奇数である事が分かります。
この様に、b0=0である事の必要十分条件がjが偶数である事や、b0=1である事の必要十分条件がjが奇数である事の理由は、式(8)を次の様に変形すると、分かります。
2m-1、2m-2、2m-3、···、21は、全て2で割り切れるため、2でくくり出すと、式(8)は式(9)の様に書き換えられます。
式(9)において、2(bm-1·2m-2+bm-2·2m-3+bm-3·2m-4+ ··· +b1·20)は必ず2で割り切れますから、b0=0であればjは偶数であり、逆(jが偶数ならばb0=0)もまた成立します。
同様の理由で、b0=1であればjは奇数であり、逆(jが奇数ならばb0=1)もまた成立します。
式(9)を見ると、括弧の中のbm-1·2m-2+bm-2·2m-3+bm-3·2m-4+ ··· +b1·20は、jを2で割った商で、b0は、jを2で割った時の余りになっている事が分かります。
この様に、jを2で割った余りを調べれば(つまりjが偶数か奇数かを調べれば)、2進数の一番下の桁のb0が確定するのですが、次に、2進数の下から2番目の桁のb1を決める方法について考えます。
先程述べたように、jを2で割った商はbm-1·2m-2+bm-2·2m-3+bm-3·2m-4+ ··· +b1·20なのですが、この数は、jを2進法で表記した時の最下位の桁を除いた、bm-1、bm-2、bm-3、···、b1の順に数字を表記した2進数の値となっている事が分かります。
この様に考えれば、jを2で割った商が偶数ならばb1=0で、jを2で割った商が奇数ならばb1=1となる事が分かります。この様にして、2進数の下2桁が確定します。
同様に、2進数の下から3桁目のb2は、jを2で割った商を、さらに2で割った商が、偶数か奇数かで決まります。
この様に、jを2でどんどん割って、割った時の余りを調べる事で、2進数の各桁の値が、下の桁から確定していくのです。
話が抽象的だったので、具体的な22という数字を、2進数に変換してみましょう。
まず、22を2で割ります。22÷2=11余り0なので、2進数の最下位の桁が0と確定します。
下から2桁目を調べるために、先ほどの商の11を、さらに2で割ります。11÷2=5余り1なので、2進数の下から2桁目が1と確定します。
下から3桁目を調べるために、先ほどの商の5を、さらに2で割ります。5÷2=2余り1なので、2進数の下から3桁目が1と確定します。
下から4桁目を調べるために、先ほどの商の2を、さらに2で割ります。2÷2=1余り0なので、2進数の下から4桁目が、0と確定します。
下から5桁目を調べるために、先ほどの商の1を、さらに2で割ります。1÷2=0余り1なので、2進数の下から6桁目が、1と確定します。
ここで商が0になりましたので、この先何回2で割っても、必ず商も余りも0になります。よって、下から7桁目以降は全て0となり、ここで計算は打ち切りです。
以上の計算から、22を2進数に変換すると、10110となりますが、この2進数を画面1の2進数を10進数に変換するツールで10進数に変換すると、確かに元の22に戻ります。
ここで書いたように、22を何回も2で割った結果を、文章と式で書くのでは、書く分量が多くなり、計算に時間がかかってしまいます。そこで図2に示す様な計算をすると、簡潔に書けて、早く計算が終わります。
図1に示した筆算により、10進数を2進数に変換するツールをSyn BASICで作りました。下の画面2で、実際に使う事ができます。
ツールを使うには、画面をクリック(またはタップ)して、入力を受け付ける状態にし、2進数に変換したい10進数を入力した後、ENTERキーを押してください。最大で10桁の10進数が入力できます。
下の実行例2は、22ENTERと入力して、22という10進数を2進数に変換した例です。10110という答えが表示されるだけではなく、図2と同様の、計算の過程も表示されている事が分かります。
10進数を2進数に変換します 2進数に変換したい10進数: 22 2)22 --- 2)11 ··· 0 --- 2) 5 ··· 1 --- 2) 2 ··· 1 --- 2) 1 ··· 0 --- 0 ··· 1 10進数の22を2進数に変換すると10110です 2進数に変換したい10進数:
大きな数字を入力すると、計算過程の表示が画面に収まらなくなりますが、画面をスクロールする事で、計算過程のすべてを見る事ができます。
参考までに、10進数を2進数に変換するツールのリストを、リスト2に示します。
10 CLS
20 PRINT "10進数を2進数に変換します":PRINT
30 INPUT "2進数に変換したい10進数: ",I
40 PRINT
50 GOSUB *ERRCHK
60 IF ERR<>0 THEN 30
70 GOSUB *DISPRESULT
80 PRINT
90 GOTO 30
100 *ERRCHK
110 IF I<0 THEN PRINT "0または正の数を入力してください":ERR=1:RETURN
120 IF I<>INT(I) THEN PRINT "整数を入力してください":ERR=2:RETURN
130 IF I>9999999999 THEN PRINT "10桁以内の数を入力してください":ERR=3:RETURN
140 ERR=0
150 RETURN
160 *DISPRESULT
170 SUB_DEC=0:SUB_SHIFT=1
180 IF I>=SUB_SHIFT THEN SUB_SHIFT=SUB_SHIFT*10:SUB_DEC=SUB_DEC+1:GOTO 180
190 SUB_RESULT$=""
200 IF I=0 THEN SUB_RESULT$="0":GOTO 440
210 SUB_D=I:SUB_R=-1
220 PRINT " 2)";
230 SUB_S$=STR$(SUB_D)
240 IF LEN(SUB_S$)<SUB_DEC THEN SUB_S$=" "+SUB_S$:GOTO 240
250 PRINT SUB_S$;
260 IF SUB_R>=0 THEN PRINT " ··· ";SUB_R;
270 PRINT
280 PRINT " ";
290 FOR SUB_J=1 TO SUB_DEC+1
300 PRINT "-";
310 NEXT SUB_J
320 PRINT
330 SUB_TEMP=INT(SUB_D/2)
340 SUB_R=SUB_D MOD 2
350 SUB_RESULT$=STR$(SUB_R)+SUB_RESULT$
360 SUB_D=SUB_TEMP
370 IF SUB_D=0 THEN 390
380 GOTO 220
390 FOR SUB_I=1 TO SUB_DEC+3
400 PRINT " ";
410 NEXT SUB_I
420 PRINT "0 ··· ";SUB_R
430 PRINT
440 PRINT "10進数の";I;"を2進数に変換すると";SUB_RESULT$;"です"
450 RETURN