LASSIC Media らしくメディア
2進数・10進数・16進数の変換方法と使われる場面
監修・編集責任者:牛尾 昭昌(株式会社LASSIC 執行役員)
この記事の結論
- 2進数・10進数・16進数の変換は、基数で割った余りを下から並べる方法と、各桁に重みを掛けて足す方法の2つで行えます。
- 2進数の4桁は16進数の1桁にそのまま対応するので、長いビット列は16進数で書くと読みやすくなります。
- 言語の変換関数には基数を省かずに渡し、桁数と大文字・小文字を仕様で決めておくと取り違えを防げます。
※ 本記事は2026年10月時点の公式情報(省庁・公的機関、および製品やサービスを提供する事業者が公開している資料)に基づきます。
2進数・10進数・16進数の変換は、設定やログを読むときにも欠かせない基礎です。CSSに書かれた #2C3338 という色、ログに並ぶ 0x で始まるアドレス、ファイルの権限の 755、ダウンロードしたファイルに添えられたハッシュ値の長い英数字。どれも10進数以外で書かれた数で、読み方を知らないと値の意味や誤りに気づけません。
本記事では、システムの開発・運用の担当者に向けて、割り算と位取りによる変換の手順、2進数4桁と16進数1桁の対応、実務で出会う場面、主な言語の変換関数と、つまずきやすい点を整理します。
目次
2進数・10進数・16進数とは
ふだん使う10進数は、0〜9の10種類の数字を使い、桁が1つ上がるごとに重みが10倍になる数の書き方です。このように桁の位置で重みが決まる書き方を位取り記数法と呼び、1桁で使える数字の種類の数を基数と呼びます。2進数は基数が2で0と1だけを使い、16進数は基数が16で、0〜9に続けてa〜fの6文字で10〜15を表します。
たとえば10進数の202は、2×100+0×10+2×1です。同じ値を2進数で書くと11001010、16進数で書くとCAになります。値は同じで、書き方だけが違います。コンピュータの内部では値を0と1の並びで持つため2進数が基本ですが、2進数は桁数が多く人には読みにくいので、表示や設定では16進数や8進数がよく使われます。
どの基数で書いたかを示すために、プログラムでは接頭辞を付けます。Pythonの整数リテラルでは、2進数に0b、8進数に0o、16進数に0xを付け、16進数の10〜15は大文字・小文字を問わずA〜Fで表します。*1
10進数から2進数・16進数への変換
10進数を別の基数に直すには、基数で割り続けて余りを書き留め、最後に余りを下から順に並べます。202を2進数にするときの計算は次のとおりです。
| 割られる数 | 2で割った商 | 余り |
|---|---|---|
| 202 | 101 | 0 |
| 101 | 50 | 1 |
| 50 | 25 | 0 |
| 25 | 12 | 1 |
| 12 | 6 | 0 |
| 6 | 3 | 0 |
| 3 | 1 | 1 |
| 1 | 0 | 1 |
商が0になったところで止め、余りを下から読むと11001010になります。最初に出た余りが一番右の桁(1の位)、最後に出た余りが一番左の桁です。上から読むと別の値になるので、並べる順番に注意します。
16進数も同じ手順で、16で割ります。202÷16は商12・余り10、12÷16は商0・余り12です。余りの10はA、12はCと書くので、下から並べてCAになります。8進数なら8で割り、202は312になります。
2進数・16進数から10進数への変換
逆向きは、各桁の数字にその桁の重みを掛けて足し合わせます。重みは右端の桁が1で、左へ1つ進むごとに基数倍になります。2進数なら右から1、2、4、8、16、32、64、128、16進数なら1、16、256、4096と増えていきます。
11001010を10進数に直すと、1が立っている桁の重みを足して、128+64+8+2=202です。16進数のCAなら、C(12)×16+A(10)×1=202になります。2進数なら、1の桁の重みを足すだけです。
桁数からは値の大きさの見当もつきます。2進数でn桁なら表せる値は0から2のn乗−1まで、16進数の2桁なら0〜255(ff)、4桁なら0〜65535(ffff)です。1バイトは8ビットなので、ちょうど16進数2桁で書けます。
2進数4桁と16進数1桁の対応
2進数と16進数の間には、10進数を経由しない近道があります。16は2の4乗なので、2進数の4桁(4ビット)がちょうど16進数の1桁に対応します。0〜15の対応は次のとおりです。
| 10進数 | 2進数 | 16進数 | 10進数 | 2進数 | 16進数 |
|---|---|---|---|---|---|
| 0 | 0000 | 0 | 8 | 1000 | 8 |
| 1 | 0001 | 1 | 9 | 1001 | 9 |
| 2 | 0010 | 2 | 10 | 1010 | A |
| 3 | 0011 | 3 | 11 | 1011 | B |
| 4 | 0100 | 4 | 12 | 1100 | C |
| 5 | 0101 | 5 | 13 | 1101 | D |
| 6 | 0110 | 6 | 14 | 1110 | E |
| 7 | 0111 | 7 | 15 | 1111 | F |
2進数を16進数にするときは、右端から4桁ずつ区切り、それぞれを表で置き換えます。11001010なら1100と1010に分かれ、1100はC、1010はAなのでCAです。桁数が4の倍数でなければ、左に0を補ってから区切ります。たとえば101101は0010と1101に分けて2Dになります。16進数を2進数にするときは、1桁ずつ4ビットに置き換えて並べるだけです。
8進数も同じ考え方で、8は2の3乗なので、2進数の3桁が8進数の1桁に対応します。11001010を右から3桁ずつ区切ると011・001・010で、312になります。16進数と8進数は、ビットの並びを人が読める長さに縮めて書くための表記です。ビットごとの論理演算やシフトそのものは「ビット演算の基礎」で扱っています。
実務で出会う16進数と8進数
身近なのがCSSの色の指定です。CSS Color Module Level 4は、#に続けて3・4・6・8桁の16進数を書く形式を定めています。6桁なら先頭から2桁ずつが赤・緑・青の強さで、00〜ff(10進数の0〜255)の値で表します。*2 たとえば#2C3338は、赤が0x2C=44、緑が0x33=51、青が0x38=56で、rgb(44 51 56)と同じ濃い灰色です。3桁の#123は各桁を重ねた#112233と同じ色で、3桁で表せる色は4096通りに限られます。
メモリアドレスも16進数で表示するのが一般的です。Cのprintf(3)では、%pを指定するとポインタの値が %#x や %#lx と同じように16進数で出力されます。*3 16進数で見ると、4096(0x1000)単位にそろったアドレスは下3桁が000になるので、境界にそろっているかどうかが一目で分かります。
8進数を日常的に使うのがファイルの権限です。GNUのchmodの説明書によれば、数値のモードは1〜4桁の8進数で、読み取り4、書き込み2、実行1を足して作ります。*4 755なら、所有者が7(4+2+1で読み・書き・実行)、グループとその他が5(4+1で読み取りと実行)です。7は2進数で111、5は101なので、8進数の1桁の3ビットが、そのまま読み・書き・実行の3つの許可に対応しています。
ハッシュ値の表示にも16進数が使われます。Pythonのhashlibでは、digest()がバイト列を返し、hexdigest()は同じ値を2倍の長さの16進数の文字列で返します。*5 SHA-256の結果は32バイト(256ビット)なので、16進数では64文字です。URLのパーセントエンコーディングも「%」の後に16進数2桁を置く形で、「URLエンコードの仕組み」で扱っています。
主な言語の変換関数
実際の変換は言語の関数に任せます。Pythonでは、int()に文字列と基数を渡すと整数になり、基数には0と2〜36を指定できます。逆向きはbin()、oct()、hex()が、それぞれ0b、0o、0x付きの文字列を返します。*6 接頭辞を外したいときや桁をそろえたいときはformat()を使い、書式のb・o・x・Xが2進数・8進数・16進数(小文字・大文字)を表し、#を付けると接頭辞が付きます。*7
>>> int('11001010', 2), int('ca', 16), int('0xCA', 0)
(202, 202, 202)
>>> bin(202), oct(202), hex(202)
('0b11001010', '0o312', '0xca')
>>> format(202, '08b'), format(202, '02X'), f'{202:#x}'
('11001010', 'CA', '0xca')
>>> format(0xdeadbeef, '_x')
'dead_beef'
書式に _ を入れると、2進数・8進数・16進数では4桁ごとに区切りが入ります。JavaScriptでは、数値のtoString()に基数を渡すとその基数の文字列になり、基数は2〜36で、範囲の外ならRangeErrorになります。*8 文字列から数値へは、parseInt()に文字列と基数を渡します。桁をそろえるには、padStart()で左に0を補います。
(202).toString(2) // "11001010"
(202).toString(16) // "ca"
parseInt("ca", 16) // 202
parseInt("11001010", 2) // 202
(5).toString(2).padStart(8, "0") // "00000101"
Cのprintf(3)では、%oが8進数、%uが10進数、%xと%Xが16進数(小文字・大文字)で、いずれも符号なしの整数として変換されます。#フラグを付けると、%oでは先頭に0が、%xでは0xが付きます。*3 たとえば printf(“%o %x %#x”, 202, 202, 202) は 312 ca 0xca を出力します。
つまずきやすい点
JavaScriptのparseInt()は、基数を省くと10進数になるとは限りません。基数を省くか0を渡すと文字列から基数が推定され、0xまたは0Xで始まる文字列は16進数として読まれます。また、基数に合わない文字が現れるとそこで読むのをやめ、それまでの値を返すので、parseInt(“12”, 2)は1を返し、parseInt(“2”, 2)はNaNになります。*9 入力の検査を兼ねるなら、基数を省かずに渡し、変換した値を文字列に戻して元と一致するかを確かめます。
Pythonのint()で基数に0を渡すと、0b・0o・0xの接頭辞から基数を決めますが、このときは先頭の0が認められず、int(‘010’, 0)はエラーになります。int(‘010’)やint(‘010’, 8)なら変換できます。*6 Pythonも3.0より前は0で始まる8進数の書き方を使っており、いまの文法が0123のようなリテラルを認めないのは、それと区別するためです。*1
負の数にも注意します。Pythonのbin(-10)は ‘-0b1010’ を返し、JavaScriptの(-10).toString(2)は ‘-1010’ を返します。MDNは、基数が2でも2の補数ではなく、「-」を付けた正の2進数の表記になると説明しています。*8 メモリ上のビット列として見るなら2の補数で考える必要があり、詳しくは「2の補数とは?負の数を表す仕組みの基礎」に譲ります。
桁数と並び順も取り違えやすい点です。16進数の値は、先頭の0を落とすと桁の位置がずれるため、1バイトなら2桁、4バイトなら8桁のように桁数を決めて0で埋めます。複数バイトの値をメモリやファイルから取り出して16進数で並べると、CPUによってバイトの順番が逆に見えることがあります。これは基数ではなくバイト順の問題で、「ビッグエンディアンとリトルエンディアンの違い」で扱っています。
桁の多い値にも気をつけます。JavaScriptの数値で64ビットの値を扱うと下の桁が丸められ、parseInt(“ffffffffffffffff”, 16)は18446744073709552000になり、正しい値の18446744073709551615と一致しません。桁の多い値はBigIntで読むか、文字列のまま比べます。
外部に委託するときに確認しておきたい点
開発や保守を外部に任せるとき、数の書き方は仕様書で曖昧になりやすい部分です。APIやファイルの項目に16進数の値があるなら、大文字か小文字か、0xの接頭辞を付けるか、何桁で0埋めするかを項目の定義に書いておきます。大文字と小文字の違いだけでハッシュ値が不一致と判定される、といった食い違いを防げます。
受け入れのテストでは、0、上限の値(1バイトならff)、先頭に0が並ぶ値、大文字と小文字が混ざった値といった境界の値を含めるよう依頼します。コードレビューでは、parseInt()に基数が渡されているか、桁の多い値を数値型で扱っていないかを確認の項目に入れます。
まとめ:基数の変換で確かめておきたい3つの点
確かめておきたい点は3つです。第一に、10進数からは基数で割った余りを下から並べ、10進数へは各桁に重みを掛けて足すという2つの手順を押さえること。第二に、2進数の4桁が16進数の1桁、3桁が8進数の1桁に対応することを使って、色やアドレス、権限の値を読むこと。第三に、言語の変換関数では基数を省かずに渡し、桁数と大文字・小文字、負の数と桁の多い値の扱いを仕様で決めておくことです。数の書き方の取り決めは、設計の段階で書き出しておきます。
よくある質問
16進数のa〜fは、大文字と小文字のどちらで書けばよいですか
値としてはどちらも同じです。CSSの色の指定では大文字と小文字を区別しません。ただしPythonのhex()は小文字を返すなど、関数によって出力がどちらかに決まっています。文字列のまま比べる場面では食い違いの元になるので、システムの中でどちらかにそろえる決まりを作っておきます。
16進数の1桁は何ビットですか
4ビットです。16は2の4乗なので、2進数の4桁が16進数の1桁にちょうど対応します。1バイトは8ビットなので16進数では2桁になり、ハッシュ値やダンプの出力が2桁ずつの組で表示されるのはこのためです。
基数に36まで指定できるのはなぜですか
0〜9の10文字とa〜zの26文字を合わせた36文字を数字として使うためです。Pythonのint()では10〜35をa〜z(大文字も可)で表し、基数には0と2〜36を指定できます。JavaScriptのtoString()も、基数に指定できるのは2〜36です。
システム開発・保守運用のご相談
元請(プライムベンダー)として、仕様の整理から開発、保守運用までご提案します。
Remoguとリラシクなら、開発や保守運用に加わるITエンジニアも探せます。
Remoguは、リモート前提で全国から即戦力のITプロ人材を調達するサービスです。リラシクは、扱う求人がすべてリモートワークのITエンジニア専門転職エージェントです。どちらもLASSICが運営しています。
出典
- *1 参考:Python Software Foundation「Lexical analysis — Python documentation」(https://docs.python.org/3/reference/lexical_analysis.html)。出典:Python 言語リファレンスのうち、整数リテラルの接頭辞(0b・0o・0x)、16進数のA〜F、先頭が0の10進数リテラルを認めない理由の記述を参照(2026年10月確認)
- *2 参考:W3C CSS Working Group「CSS Color Module Level 4」(Editor’s Draft)(https://drafts.csswg.org/css-color-4/)。出典:5.2節 The RGB Hexadecimal Notations のうち、3・4・6・8桁の16進数表記、00〜ffの意味、3桁表記の展開と4096通りの記述を参照(2026年10月確認)
- *3 参考:Linux man-pages「printf(3) — Linux manual page」(man7.org)(https://man7.org/linux/man-pages/man3/printf.3.html)。出典:変換指定子 o・u・x・X と p、フラグ # の記述を参照(2026年10月確認)
- *4 参考:Linux man-pages「chmod(1) — Linux manual page」(man7.org)(https://man7.org/linux/man-pages/man1/chmod.1.html)。出典:数値モードが1〜4桁の8進数で、読み取り4・書き込み2・実行1を足して作るという記述を参照(2026年10月確認)
- *5 参考:Python Software Foundation「hashlib — Secure hashes and message digests」(https://docs.python.org/3/library/hashlib.html)。出典:digest() と hexdigest() の違い(2倍の長さの16進数の文字列)と sha256 の使用例を参照(2026年10月確認)
- *6 参考:Python Software Foundation「Built-in Functions — Python documentation」(https://docs.python.org/3/library/functions.html)。出典:int()(基数0と2〜36、接頭辞、基数0での先頭0の扱い)、bin()・oct()・hex() の記述と使用例を参照(2026年10月確認)
- *7 参考:Python Software Foundation「string — Format Specification Mini-Language」(https://docs.python.org/3/library/string.html)。出典:整数の表示型 b・o・x・X、# オプション、_ オプション(2進数・8進数・16進数では4桁ごと)の記述を参照(2026年10月確認)
- *8 参考:MDN Web Docs「Number.prototype.toString()」(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString)。出典:radix の範囲(2〜36)と RangeError、負の数は2の補数でなく符号付きの表記になるという記述を参照(2026年10月確認)
- *9 参考:MDN Web Docs「parseInt()」(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt)。出典:radix を省いたときの推定、0x・0X の扱い、基数に合わない文字で読むのをやめる動作の記述を参照(2026年10月確認)