header image

枝折

基数と基数変換のはなし

CS

CREATED: 2026 / 05 / 07 Thu

UPDATED: 2026 / 05 / 07 Thu

基数に関する話をしてみます。

基数とは

基数は 2/8/10/16 進数でいうところのこの数値の部分のことです。 人間が一般に使っている 10 進数は 0〜9 の 10 種類の数字を扱い、これの基数は 10 となります。

人間にとっては使いづらいものですが、コンピュータの世界では 2/8/16 進数も使われます。

進数基数使用する数字・記号
2 進数20, 1
8 進数80〜7
10 進数100〜9
16 進数160〜9, A(10), B(11), C(12), D(13), E(14), F(15)

2進数・8進数・16進数の表現

2進数(Binary)

2 進数は 0 と 1 の 2 種類だけで数を表します。 桁が上がるたびに値が 2 倍になります。

10 進数2 進数
00000
10001
20010
30011
40100
50101
60110
70111
81000

表記上は 0b0B を先頭に付けたり、末尾に (2) と添えることもあります(例:0b10101010(2))。

8進数(Octal)

8 進数は 0〜7 の 8 種類で数を表します。 3 bits がちょうど 1 桁の 8 進数に対応するため、2 進数との相互変換が容易です。

10 進数8 進数
00
77
810
1517
1620
6377
64100

表記上は先頭に 00o を付けたりします(例:0170o17)。

16進数(Hexadecimal)

16 進数は 0〜9 と A〜F の 16 種類で数を表します。 4 bits がちょうど 1 桁の 16 進数に対応するため、バイト列の表記によく使われます。

1 byte は 8 bits なので 16 進数だと 2 桁で表現できます。

10 進数16 進数
00
99
10A
15F
1610
255FF
256100

表記上は先頭に 0x0X を付けたりします(例:0xFF0x1A)。

n進数から10進数への変換

n 進数の各桁の値とその基数の桁数乗をかけたものの総和として 10 進数を求めることができます。 ちなみに、整数部の右端の桁は 0 桁目と考えます。

各桁の値 × n^(桁の位置) の総和

2進数 → 10進数の例

1101(2) を 10 進数に変換するとこんな感じです👇

1 × 2^3 + 1 × 2^2 + 0 × 2^1 + 1 × 2^0
= 8 + 4 + 0 + 1
= 13

小数部があった場合は、その内で最も左側の数値の桁数は -1 桁目と考えます。

1101.011(2) を 10 進数に変換するとこんな感じです👇

1 × 2^3 + 1 × 2^2 + 0 × 2^1 + 1 × 2^0 + 0 × 2^-1 + 1 × 2^-2 + 1 × 2^-3
= 8 + 4 + 0 + 1 + 0 + 0.25 + 0.125
= 13.375

8進数 → 10進数の例

145(8) を 10 進数に変換するとこんな感じです👇

1 × 8^2 + 4 × 8^1 + 5 × 8^0
= 64 + 32 + 5
= 101

16進数 → 10進数の例

2F(16) を 10 進数に変換するとこんな感じです👇

2 × 16^1 + 15 × 16^0
= 32 + 15
= 47

10進数からn進数への変換

10 進数を n 進数に変換するには、商が 0 になるまで基数で割り続け、余りを逆順に並べます。

10進数 → 2進数の例

13 を 2 進数に変換するとこんな感じです👇

13 ÷ 2 = 6 余り 1
 6 ÷ 2 = 3 余り 0
 3 ÷ 2 = 1 余り 1
 1 ÷ 2 = 0 余り 1

余りを下から順に並べると: 1101(2)

10進数 → 8進数の例

101 を 8 進数に変換するとこんな感じです👇

101 ÷ 8 = 12 余り 5
 12 ÷ 8 =  1 余り 4
  1 ÷ 8 =  0 余り 1

余りを下から順に並べると: 145(8)

10進数 → 16進数の例

47 を 16 進数に変換するとこんな感じです👇

47 ÷ 16 = 2 余り 15(F)
 2 ÷ 16 = 0 余り 2

余りを下から順に並べると: 2F(16)

n進数からm進数への変換

一旦10進数に変換してからm進数に変換する

n 進数を m 進数に変換する過程で一旦 10 進数に変換してあげれば、n 進数から 10 進数への変換と 10 進数から m 進数への変換だけで目的を達成できます。

n進数 → 10進数 → m進数

たとえば 1101(2) を 8 進数に変換する場合はこんな感じになります👇

1101(2) → 13(10) → 15(8)

まあ、正直これだけでもいい気はしますが、直接変換する方法も使いこなしておきたい👀

2進数から8進数へ直接変換する

2 進数 3 桁がちょうど 8 進数 1 桁に対応するので、右端から 3 bits ずつをひとまとめにして 8 進数に置き換えることができます。

この方法で 101110(2) を 8 進数に変換すると、以下のように 101110 をひとまとめにしてそれぞれ 8 進数の 1 桁として扱います👇

101 110
 5   6
= 56(8)

56(8) を 2 進数に変換する場合は、56 を 2 進数に展開すれば良いです。

5 → 101
6 → 110
= 101110(2)

2進数から16進数へ直接変換する

16 進数の場合は 2 進数 4 桁がその 1 桁に対応するので、右端から 4 bits ずつ 16 進数にして変換することができます。

ということで、10111110(2) を 16 進数に変換します👇

1011 1110
  B    E
= BE(16)

BE(16) を 2 進数に変換する場合は、BE を 2 進数に展開します。

B(11) → 1011
E(14) → 1110
= 10111110(2)

四則演算

四則演算も正直一旦 10 進数に直して計算してから答えを目的の基数に変換すればいいです。

が、一応各基数のまま計算する方法についても触れます。

足し算

2 進数の足し算でも 10 進数と同じように基数(つまり 2)以上になったら繰り上がりが発生します。

繰り上げルール:
0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 10(0を書いて1を繰り上げ)

0101(2) + 0011(2) を筆算で求めると以下のような感じになります👇

  0 1 0 1
+ 0 0 1 1
---------
  1 0 0 0

1 桁目、2 桁目、3 桁目で繰り上がりが発生することで、4 桁目に 1 が立ち、結果 1000(2) になるという感じですね👀

念の為、10 進数で確認すると、5 + 3 = 8 = 1000(2) となります。

8/16 進数も同様に、各桁の和が基数以上になったら繰り上げれば良いです。

8進数の例

15(8) + 07(8) を計算します。

1桁目: 5 + 7 = 12 → 8 以上なので、溢れた 4 だけを1桁目に書いて 1 繰り上げ
2桁目: 1 + 0 + 1(繰り上げたやつ) = 2

  1 5
+ 0 7
-----
  2 4

10 進数で確認すると、13 + 7 = 20 = 24(8) となってます。

16進数の例

1A(16) + 2F(16) を計算します。

1桁目: A(10) + F(15) = 25 → 16 以上なので、溢れた 9 だけを書いて 1 繰り上げ
2桁目: 1 + 2 + 1(繰り上げたやつ) = 4

  1 A
+ 2 F
-----
  4 9

10 進数で確認すると、26 + 47 = 73 = 49(16) となってます。

引き算

2 進数の引き算も 10 進数のやり方と考え方は同じです。

引けない時(引くとマイナスになってしまう時)は、上の桁から値を借りてきます。

例:1000(2) - 0011(2) を計算します。

  1 0 0 0
- 0 0 1 1
---------
  0 1 0 1

1000(2) は 1 桁目、2 桁目、3 桁目が 0 なので、一番上の 1 を借りてくる必要があります。

1 桁目までバケツリレーして 1 をおろしてきて計算します。

  • 1 桁目は 10(2) から 1(2) を引いて 1(2)
  • 2 桁目は 1(2) から 1(2) を引いて 0(2)
  • 3 桁目は 1(2) から 0(2) を引いて 1(2)
  • 4 桁目は 1 を下ろしたことで何も残っておらず、0(2) から 0(2) を引いて 0(2)

という感じです🙆‍♂️

10 進数で確認すると、8 - 3 = 5 = 0101(2) となってます。

8/16 進数も同様に、引けない桁が出てきたら上の桁から借りてきます。

8進数の例

24(8) - 07(8) を計算します。

1桁目: 4 - 7 → 引けないので上の桁から 8 を借りてくる → 12(4 + 8) - 7 = 5
2桁目: 2 - 1(借りたやつ) - 0 = 1

  2 4
- 0 7
-----
  1 5

10 進数で確認すると、20 - 7 = 13 = 15(8) となってます。

16進数の例

49(16) - 2F(16) を計算します。

1桁目: 9 - F(15) → 引けないので上の桁から 16 を借りてくる → 25(9 + 16) - 15 = 10(A)
2桁目: 4 - 1(借りたやつ) - 2 = 1

  4 9
- 2 F
-----
  1 A

10 進数で確認すると、73 - 47 = 26 = 1A(16) となってます。

掛け算

2 進数の掛け算は筆算では以下のようにやります(10 進数と変わんないです)👇

例:0101(2) × 0011(2) を計算します。

      0 1 0 1   (= 5)
    × 0 0 1 1   (= 3)
-------------
      0 1 0 1   (0101 × 1、0桁シフト)
    0 1 0 1   (0101 × 1、1桁シフト)
  0 0 0 0
0 0 0 0
-------------
0 0 0 1 1 1 1   (= 15)

上の 2 進数と下の 2 進数の各桁(1 桁目から順に)の積(AND を取る)を桁をずらしながら書いていき、それを最後に足し合わせるような感じです。

8進数の例

15(8) × 3(8) を計算します。

1桁目: 5 × 3 = 15 → 8 以上なので 7 を書いて 1 繰り上げ(15 = 8 + 7)
2桁目: 1 × 3 = 3、これに繰り上げた 1 を足して 4

  1 5
×   3
-----
  4 7

10 進数で確認すると、13 × 3 = 39 = 47(8) となってます。

16進数の例

1A(16) × 3(16) を計算します。

1桁目: A(10) × 3 = 30 → 16 以上なので E(14) を書いて 1 繰り上げ(30 = 16 + 14)
2桁目: 1 × 3 = 3、これにくりあげた 1 を足して 4

  1 A
×   3
-----
  4 E

10 進数で確認すると、26 × 3 = 78 = 4E(16) となってます。

割り算

2 進数の割り算は 10 進数の割り算と同じような感じでできます👇

1111(2) ÷ 11(2) を計算します。

        1 0 1
      -------
1 1 ) 1 1 1 1
      1 1
      -------
        0 1
          0
          ---
          1 1
          1 1
          ---
            0

10 進数で確認すると、15 ÷ 3 = 5 = 101(2) となってます。

8進数の例

47(8) ÷ 3(8) を計算します。

      1 5
      ---
  3 ) 4 7
      3      (3 × 1 = 3)
      ---
      1 7
      1 7    (3 × 5 = 17(8))
      ---
        0

10 進数で確認すると、39 ÷ 3 = 13 = 15(8) となってます。

16進数の例

4E(16) ÷ 3(16) を計算します。

      1 A
      ---
  3 ) 4 E
      3      (3 × 1 = 3)
      ---
      1 E
      1 E    (3 × A(10) = 30 = 1E(16))
      ---
        0

10 進数で確認すると、78 ÷ 3 = 26 = 1A(16) となってます。

小数の扱い

10進小数と2進小数の変換

10進小数 → 2進小数

整数部は前述の「10 進数 → n 進数変換」と同じですが、小数部は別のやり方で求めます。

まず、小数部を 2 倍し、その結果の整数部が 1 以上になれば 1、1 未満ならば 0 を記録します。 そして、この作業を小数部が 0 になるまで繰り返し、得られた 0 と 1 を順に並べることによって 2 進数小数を導きます。

例:0.625 を 2 進数に変換します。

0.625 × 2 = 1.25 → 1(整数部を取り出し、残りの 0.25 で続ける)
0.25  × 2 = 0.5  → 0
0.5   × 2 = 1.0  → 1(小数部が 0 になったので終了)

上から順に並べると: 0.101(2)

確認として、0.101(2) から 10 進数を求めてみます。

1 × 2^(-1) + 0 × 2^(-2) + 1 × 2^(-3) = 0.5 + 0 + 0.125 = 0.625 ですね。

ちなみに 10 進小数のすべてが有限の 2 進小数で表せるとは限りません。 たとえば 0.1(10) は 2 進数では 0.0001100110011...(2) と無限循環小数になります。

これがいわゆる丸め誤差が生まれる理由ですね👀

どんなシステムでも無限の値を扱うことはできないので、この桁数を有限の値に制限するのですが、そうすると四捨五入や切り捨てが発生していまいます。 その結果システムに元々入力した値とずれた値が生まれてしまいます(後で再取得したときにずれが起きる)。

2進小数 → 10進小数

こっちは 2 進数整数から 10 進数整数を出すときと同じ感じで、各桁のインデックスをかけてそれを足し合わせれば良いです🙆‍♂️

例:0.1011(2) を 10 進数に変換します。

1 × 2^(-1) + 0 × 2^(-2) + 1 × 2^(-3) + 1 × 2^(-4)
= 0.5 + 0 + 0.125 + 0.0625
= 0.6875

2 進数のシフト演算による小数の乗除

シフト演算を使えば掛け算と割り算を楽に行えます。

  • 左シフト(<<)n ビット → 2^n 倍(掛け算)
  • 右シフト(>>)n ビット → 2^(-n) 倍(割り算)

たとえば、0101(2)(= 5) を 1 ビット左シフトすると 1010(2)(= 10)、つまり 2 倍することができます。

0 1 0 1  (5)
左シフト 1 bit
1 0 1 0  (10 = 5 × 2)

1000(2)(= 8) を 2 ビット右シフトすると 0010(2)(= 2)、つまり 1/4 倍することができます。

1 0 0 0  (8)
右シフト 2 bits
0 0 1 0  (2 = 8 ÷ 4)

ちなみに、整数だけを扱う場合、右シフトすると右端が失われます。 たとえば 0101(2)(= 5) を 1 ビット右シフトすると 0010(2)(= 2) となり、1 が失われます。

を仕舞い

CS の記事も書いていきたいなと思ったのでタグを追加しました💪