電話 0422-27-7828チャットで質問無料相談を予約

武蔵野個別指導塾の特徴

【情報I】デジタル化の仕組みを図解で総まとめ—2 進法・16 進法・ビットとバイト・情報量|武蔵野個別指導塾

【情報I】デジタル化の仕組みを図解で総まとめ—2 進法・16 進法・ビットとバイト・情報量のアイキャッチ 武蔵野個別指導塾
X LINE Facebook

2進法の桁の図から16進法への変換、必要なビット数、2の補数までをたどります。変換と情報量の例題を手順に沿って解き、同じビット列の意味が表現の約束で変わる理由を確かめましょう。

よくあるのは、塾の面談の席で「2進法の1011は、なぜ千十一ではなく11なのですか」と聞かれ、計算の手順は思い出せても理由を説明できないという場面です。保護者の方がお子さまのノートを見ると、2で割る計算は並んでいるのに、余りを下から読む理由が書かれていません。ここで必要なのは、新しい計算を大量に覚えることではなく、数の大きさと、その大きさを書き表す方法を分けることです。

同じ人数を「11」と書くか「1011」と書くかは、使う進法によって変わります。また、同じ4桁のビット列でも、負の数を含む約束で読むと意味が変わります。この単元を学ぶと、進法を変換するだけでなく、何通りの状態を何ビットで区別できるか、なぜ桁数を決めないと負の数を扱えないかまで説明できるようになります。数字の列を見る前に、その列を読む約束を確認していきましょう。

この単元で身につけること

小学校で学んだ十進位取り記数法が、ここでの出発点です。10進法で百の位・十の位・一の位を分けるのと同じように、2進法では4の位・2の位・1の位を分けます。難しく感じたら、変換の操作を暗記する前に、右端の桁が何個分を表すのかを口に出して確かめてください。

基本の考え方

アナログからデジタルへは、値の区別の仕方を変える

アナログとは、情報を連続的に変化する量で表す方法です。例えば、針の位置を連続的に動かして温度に対応させる表示では、途中の位置も表現に使えます。一方、デジタルとは、情報を離散的な値、つまり飛び飛びに区別できる値で表す方法です。温度を1℃刻みで記録するなら、20℃と21℃の間の細かな違いは、その記録の中では残りません。

ここで「数字で表示されていれば、元の量も飛び飛びである」と考えないことが大切です。元の温度が連続的に変化していても、測って記録する段階で一定の刻みに分けられます。細かい刻みにすれば区別できる値は増えますが、その分だけ記録に必要な桁数も増えることがあります。現実の何を残し、どこまで区別するかという約束が先にあります。

コンピュータでは、情報を0と1の組み合わせに対応させて扱います。実際の機器の中では電気的な状態などを区別していますが、その状態を表す記号として0と1を用います。0と1は「数字以外を扱えない」という意味ではありません。文字にも色にも音にも、それぞれの状態に対応する符号を割り当てれば、ビット列として保存できます。

デジタル化されたデータは、0と1を正しく識別できる範囲なら、元と同じビット列として複製しやすいという特徴があります。ただし、測定や段階分けのときに失った細かさが、複製によって復活するわけではありません。「複製しても同じデータ」と「現実を無限に細かく記録できる」は別の話です。この区別が、画像や音のデータ量を学ぶときにも役立ちます。

進法は、桁がいくつで繰り上がるかという約束

10進法で使う数字は0から9です。一の位が9の次になると、十の位を1増やして一の位を0にします。右端から各桁の重みは1、10、100、1000と10倍ずつになります。例えば253は、2×100+5×10+3×1という意味です。数字の並びの意味は、位置によって決まっています。

2進法で使う数字は0と1です。右端から重みは1、2、4、8、16と2倍ずつになり、1の次では繰り上がります。数える順序は0、1、10、11、100です。ここでの10は、10進法での2を表しています。混乱を防ぐため、本文では1011₂のように右下の2で2進法を示し、必要に応じて11₁₀のように10進法も明記します。

図1のように、1011₂の各桁を重みの下に置くと、足すべき値が見えます。1がある桁の8、2、1を足して11となり、0がある4の位は足しません。0の桁は不要な飾りではなく、「この重みを使っていない」という位置の情報を保っています。途中の0を消すと、左右の桁の位置がずれて別の値になります。

図1 2進法の各桁の重みと十進数への変換

16進法では0から9に続き、A、B、C、D、E、Fを用いて10から15を表します。その次が10₁₆で、10進法では16です。各桁の重みは右から1、16、256となります。例えば2D₁₆は2×16+13×1です。Dを新しい未知数として計算するのではなく、13を表す1桁の記号として読んでください。

16=2⁴なので、16進法の1桁は2進法の4桁に対応します。この性質を使えば、長いビット列を短く読みやすく書けます。16進法に書き換えたから情報が圧縮されたわけではなく、同じビット列を表記するための記号が変わっただけです。進法の変換では、表している値そのものは変わりません。

ビット数は、区別できる状態の数と結びつく

ビットは、0または1のどちらかを表す情報の単位です。1ビットでは2通り、2ビットでは00、01、10、11の4通りを区別できます。桁を1つ増やすたびに、それまでの各組み合わせの後ろへ0か1を付けられるので、状態数は2倍になります。したがって、nビットのビット列は2ⁿ通りです。

8ビットを1バイトと呼びます。8ビットの状態数は2⁸=256通りであり、8バイトなら64ビットです。ビットとバイトでは8倍の違いがあるため、計算の途中でも単位を付けます。略記のbitとBを使う場合、Bはバイトを表すものとして読みます。大きい単位への換算は問題に示された約束を確認し、1000倍の区切りか1024倍の区切りかを勝手に補わないようにします。

N通りの対象すべてに同じ長さのビット列を割り当てるには、2ⁿがN以上になる最小の整数nが必要です。例えば5種類なら、2ビットの4通りでは不足し、3ビットの8通りなら足ります。余った符号があってもかまいません。全種類を重複なく区別できることが条件です。

情報量という語は、保存するデータの長さだけでなく、「知らせを受けてどれだけ不確かさが減るか」を表す場合にも使います。等しい確率で起こる8通りのうち、どれが起こったかを知る情報量は3ビットです。等確率のN通りならlog₂Nビットと表せますが、その値は整数とは限りません。1個ずつ固定長で記録するためのビット数は整数なので、情報量の値と必要な記録長は常に同じとは限らないのです。以下の符号割当ての問題では、固定長で記録すると明示して考えます。

例題で解き方を確かめる

例題1 2進法と10進法を往復する

101101₂を10進法に直し、得られた整数を2進法に戻してください。最初に桁の重みで値を求め、次に割り算で同じ並びが戻るかを確かめます。片道の計算だけで終わらせないと、余りの読み違いを見つけやすくなります。

  1. 6桁の下に、左から32、16、8、4、2、1を置きます。右端が1で、左に進むたびに2倍になるからです。
  2. 1のある桁の重みを足します。32+8+4+1=45です。16の位と2の位は0なので、合計に加えません。
  3. 45を2で割り、商をさらに2で割ります。45÷2は商22余り1、22÷2は商11余り0、11÷2は商5余り1、5÷2は商2余り1、2÷2は商1余り0、1÷2は商0余り1です。
  4. 余りを最後から最初へ読み、101101とします。最初の余りは一の位で、その後の余りほど左の桁を表すからです。

答え:101101₂=45₁₀であり、45₁₀を2進法へ戻すと101101₂です。

なぜ割り算の余りが各桁になるのでしょうか。整数は「2×商+余り」と書けて、余りは0か1です。最初の割り算で偶数か奇数か、つまり右端の1の位が決まります。商をもう一度割ると、元の数の2の位が決まります。下から読む手順は、この取り出す順序を逆にしているだけです。

Pythonでも同じ対応を確かめられます。intの第2引数の2は、文字列を2進法として読む指定です。formatのbは整数を2進法の文字列にする指定で、ここでは手計算の答えの確認に使います。

value = int("101101", 2)
print(value)
print(format(value, "b"))

出力は次のとおりです。値は整数の45のままで、表示に使う進法だけが変わっています。

45
101101

例題2 2進法と16進法を対応させる

101101₂を16進法に直し、その16進数から10進法の値を確かめてください。2進法をいったん10進法へ直してから計算する方法もありますが、ここでは4桁ごとの対応を使います。まとまりを右端から作ることが要点です。

  1. 右から4桁ずつに分け、10と1101にします。16進法の一の位が、2進法の右端4桁に対応するからです。
  2. 左のまとまりだけが2桁なので、先頭に0を補って0010とします。左端に0を付けても、非負の整数としての値は変わりません。
  3. 0010は2、1101は8+4+1=13なのでDに対応させます。図2では、各4桁のまとまりが16進法の1桁へつながっています。
  4. 得られた2D₁₆を2×16+13と読み、45になることを確かめます。例題1と一致するので、まとまりの取り方も確認できます。

答え:101101₂=2D₁₆=45₁₀です。

図2 2進数を右から4桁ずつまとめる16進変換

図2のように0を補う場所は左端です。右端に0を付けると、各桁が1つ左に移動し、非負の整数の値は2倍になります。また、16進法の1桁を2進法へ戻すときは、途中のまとまりを必ず4桁でそろえます。例えば20₁₆を2と0の変換結果だけで並べて100₂にすると誤りです。0010と0000を並べることで、16の位という位置を保てます。

例題3 必要なビット数と保存量を求める

50種類の記号に、すべて同じ長さのビット列を割り当てます。1個の記号を区別する最小のビット数はいくつでしょうか。また、その最小ビット数で120個を隙間なく詰めて保存すると、データ部分は何バイトでしょうか。区切りや管理用の追加データは含めません。

  1. 状態数を比べます。2⁵=32では50種類に足りず、2⁶=64なら足ります。種類数を8で割るのではなく、まず種類数を収める符号の長さを決めます。
  2. 1個を6ビットとします。64通りのうち50通りを使えば、14通りは未使用のままでよいからです。
  3. 120個分を掛け、6×120=720ビットとします。1個あたりの長さに個数を掛けることで、保存するビット列全体の長さになります。
  4. 1バイト=8ビットなので、720÷8=90バイトとします。今回は割り切れるため、最後のバイトを埋める余りはありません。

答え:1個に必要な最小ビット数は6ビットで、120個のデータ部分は90バイトです。

1個ずつ必ず1バイトの領域に保存する方式なら、120個で120バイトになります。90バイトという答えには「6ビットずつ隙間なく詰める」という条件が効いています。実際の保存量を尋ねる問題では、理論上の最小ビット数だけでなく、保存する単位や余白の条件も読みます。

次のコードは、状態数が50以上になるまでビット数を1ずつ増やします。最後の行の//は整数の商を求める演算で、今回は720が8で割り切れることを確かめてから使っています。

kinds = 50
bits = 0
while 2 ** bits < kinds:
    bits += 1
print(bits)
print(bits * 120 // 8)

出力は次のとおりです。1行目は1個の符号の長さ、2行目は120個分のバイト数なので、同じ種類の値ではありません。

6
90

例題4 8ビットの2の補数で負の整数を表す

8ビットの2の補数表現で−5を表してください。さらに、+5のビット列を足すと、8ビット内で0になることを確かめてください。負の数を作る前に、8ビットという幅を固定することが大切です。

  1. +5を8桁で書き、00000101とします。反転する範囲を決めるために、左端の0も書きます。
  2. すべての0と1を入れ替え、11111010とします。この段階はビットの反転であり、まだ−5の2の補数表現ではありません。
  3. 1を加えて11111011とします。「反転して1を加える」という手順で、8ビット内で+5を打ち消す並びを作ります。
  4. 00000101+11111011=1 00000000を確かめます。最上位の外へ出た1を保存せず、下位8ビットだけを残すと00000000になります。

答え:−5の8ビット2の補数表現は11111011で、+5との和の下位8ビットは00000000です。

別の読み方でも確かめられます。11111011を符号なしとして読むと251です。8ビットの2の補数として最上位ビットが1なら、その値から256を引いて読みます。251−256=−5となり、反転して1を加える方法と一致します。次のコードでは、%を余りを求める演算として使い、256で割った余りによって下位8ビットの範囲に戻しています。

width = 8
encoded = (-5) % (2 ** width)
print(format(encoded, "08b"))
print(encoded - 2 ** width)
print(format((encoded + 5) % (2 ** width), "08b"))

出力は次のとおりです。08bは、2進法の表示が8桁になるように左側を0で埋める指定です。

11111011
-5
00000000

つまずきやすいところと直し方

桁の重みを足す代わりに、見えた数字をそのまま読む

誤った書き方:1011₂=1011₁₀です。どこが違うかというと、左端の1が表す重みを、2進法でも1000だと思っています。正しい書き方は、1011₂=1×8+0×4+1×2+1×1=11₁₀です。桁の重みを書き足してから計算すれば、見た目の並びに引きずられずに済みます。

進法が不明なまま「10」とだけ書かれたら、その文字列だけでは値を一意に決められません。答案では、変換前後の進法を言葉や添字で示すと、途中の計算の意味が伝わります。ただし2進法の数に2や3を使うことはできません。使える数字を先に確認するだけでも、計算を始める前に誤りを発見できます。

状態の総数と最大値を同じにする

誤った書き方:8ビットで表せる符号なし整数の最大値は256です。どこが違うかというと、0という状態を数え落としています。正しい書き方は、状態数が256通りで、整数としての範囲は0から255です。4ビットなら16通りで0から15、1ビットなら2通りで0と1と、小さい場合に戻すと確かめやすくなります。

同じ区別は「16種類を区別する」と「整数16までを0も含めて保存する」にも現れます。前者は4ビットで足りますが、後者は17通り必要なので5ビットです。何を1通りとして数えているのかを、問題文の名詞に戻って確認してください。情報量の式を使う前に対象を数えることが、遠回りに見えて確実です。

負の数を作るときに最上位ビットだけを変える

誤った書き方:4ビットで+5が0101なので、2の補数で−5は1101です。どこが違うかというと、2の補数を、符号の桁だけを付け替える別の表現方法と混同しています。正しい書き方は、0101を反転して1010にし、1を足して1011です。2の補数表現の1101は−3なので、最上位ビットを変えるだけでは目的の値になりません。

図3のように4ビットの1011を読むと、符号なしでは8+2+1=11です。2の補数では左端の重みを−8と読み、−8+2+1=−5になります。最上位ビットが1なら負だと判断できますが、その桁を取り除いた残りが絶対値になるわけではありません。

図3 同じ4ビット列を符号なしと2の補数で読む

図3の下段にある負の重みから、4ビットの2の補数の範囲は−8から7とわかります。8ビットなら−128から127で、0を含む非負側が128通り、負側が128通りです。−8を4ビットで表した1000に反転と加算を行っても1000に戻るのは、+8がこの範囲に入らないためです。桁数を固定すると、すべての計算結果を表せるわけではありません。

例えば4ビットの2の補数で7+1を計算すると、0111+0001=1000となります。1000は−8の表現なので、数学上の和8と一致しません。これは表現範囲を超えるオーバーフローです。最上位の外へ出た桁を捨てる操作と、符号つき整数の計算が範囲内に収まるかという判断は分けてください。外へ出る桁がなくても、この例のようにオーバーフローは起きます。

練習問題

練習1

11010₂を10進法に直してください。また、19₁₀を2進法に直してください。どちらも、最後に桁の重みを使った足し算を書き、元の整数に一致するかを確かめます。

練習2

3A₁₆を8桁の2進法と10進法に直してください。また、11100101₂を16進法に直してください。16進法のAが表す数と、4桁の区切りを取り始める側に注意して取り組みます。

練習3

20種類の記号を同じ長さのビット列で区別するとき、1個に必要な最小ビット数はいくつですか。その長さで40個を隙間なく保存するデータ部分は何バイトですか。さらに、等確率の16通りから結果を1つ知る情報量を求めてください。管理用の追加データは含めません。

練習4

8ビットの2の補数表現で−12を表してください。次に、11110110を8ビットの2の補数として10進法で読んでください。どちらも、ビットの反転だけで計算を止めないようにします。

答えと解説

練習1の答えは26₁₀と10011₂です。11010₂は16+8+2=26です。19は16+2+1なので、16、8、4、2、1の位に順に1、0、0、1、1を置きます。割り算で得た余りの並びも、この足し算で確認できます。

練習2の答えは、3A₁₆=00111010₂=58₁₀、11100101₂=E5₁₆です。3を0011、Aを1010として並べると8桁になります。10進法では3×16+10=58です。後半は1110と0101に分け、14をE、5を5へ対応させます。

練習3の答えは、最小5ビット、25バイト、4ビットです。2⁴=16では20種類に足りず、2⁵=32なら足ります。40個分は5×40=200ビットで、200÷8=25バイトです。最後は16=2⁴なので、等確率の16通りから1つを知る情報量は4ビットになります。

練習4の答えは11110100と−10です。+12は00001100で、反転すると11110011、1を足すと11110100です。後半の11110110を符号なしで読むと246なので、246−256=−10となります。反転して1を足すと00001010になることからも、絶対値が10だと確かめられます。

次の単元へのつながりと家庭での確かめ方

この単元の先では、文字に符号を割り当てたり、画素の色や音の大きさをビット列にしたりします。どの場面でも「何種類を区別するか」「1個を何ビットで表すか」「何個分を保存するか」の順に考える点は共通です。画像の横幅と高さを掛ける前にも、1画素に割り当てる情報の量を確認する必要があります。

家庭で5分ほど使うなら、次の2つが確かめやすい方法です。計算結果だけでなく、途中で使った約束を1つ説明できるかも見てください。

個別指導でつまずきを確かめるときは、進法の変換に入る前の「十の位は一が何個分か」まで戻ることがあります。ビット数の問題なら、まず2枚の紙に0か1を書いて4通りを作り、式の2ⁿが何を数えているのかを確かめます。

まとめ

ビット列を読むときには、まず進法、桁数、符号の扱いを確かめます。この3つを書き添えれば、変換の途中で迷ったときも、どの約束に戻ればよいかが見えます。答えの数だけが合っていても、条件が変われば同じ操作が使えないことがあります。例えば先頭の0は非負整数の値を変えませんが、固定幅の補数表現では桁数を決める役割があります。

1011が11にも−5にもなる理由を自分の言葉で説明できたとき、0と1の列は意味を持つ情報になります。

本気になった日が、入塾の日。

お子様の教育、迷ったら「丸投げ」してください。必ず、期待以上の結果で返します。武蔵野で育む、武蔵境で学ぶ。

電話は年中無休。365日、24時間、お電話可能。

お電話 チャットで質問チャット