基数変換ツール

数値を 2 進、8 進、10 進、16 進、および 2 から 36 までの任意の基数で相互変換。固定幅の 2 の補数とビットグリッド付き。

ビット幅
2 進数
8 進数
10 進数
16 進数
基数
ビット — クリックで反転

幅 8 ビット、うち 8 個が立っています

このツールの役割

同じ数はいくつもの基数で書け、プログラマーはそのうち 4 つの間を絶えず行き来します: ハードウェアが保持するものだから 2 進数、2 進数の読める略記だから 16 進数、人がそう考えるから 10 進数、そしてファイルの権限といくつかの古いシステムが今も使うから 8 進数です。ここのどの欄に値を入力しても残りが従い、加えて 2 から 36 までの任意の基数に設定できるもう一つの欄も付いてきます。

これを学校の電卓と分けるのは、ビット幅の選択とビットのグリッドです。8・16・32・64 ビットを選ぶと、負の数はマイナス記号ではなく本物のマシン表現を得て、すべてのビットがクリックできるものになります。

基数とは実際に何か

基数とは、使い切って繰り上げるまでにいくつの数字があるかです。10 進数には 10 個あるので、9 の後は 10 です。2 進数には 2 個あるので、1 の後は 10 です。各桁の位置は基数の累乗で、それがすべてです:

1011           # この数を 2 進数で
1 x 8 = 8      # ビット 3
0 x 4 = 0      # ビット 2
1 x 2 = 2      # ビット 1
1 x 1 = 1      # ビット 0
8+0+2+1 = 11   # 合計を 10 進数で

10 を超える基数には 10 個より多い数字記号が要るので、文字を借ります: 16 進数は 0-9 の後 a-f と進み、a は 10、f は 15 です。それは基数 36 まで続き、そこはすべての数字とすべての文字を使います — 素のアルファベットで書ける最大の基数で、このツールがそこで止まる理由です。

なぜ 16 進数で、ほかの何かではないのか

16 進数は一つの特定の理由で人気です: 16 は 2 の 4 乗なので、ちょうど 1 桁の 16 進数がちょうど 4 ビットを覆います。それにより 16 進数と 2 進数の変換は計算なしの参照になります — 各 16 進数の桁が、周りの桁と独立に、自分の 4 ビットに展開されます。

d    e    a    d
1101 1110 1010 1101   # 各 16 進数の桁がそれぞれのニブル

8 進数は 1 桁 3 ビットで同じように働きます。8 は 2 の 3 乗だからです — だから Unix の権限は 8 進数なのです: ユーザーのグループごとの 3 つの権限ビットがちょうど 1 桁に収まります。10 進数は 2 進数とそのような関係を持たず、だから両者の変換には参照ではなく本物の割り算が要ります。

だからここの 2 進数の欄は 4 つずつ、16 進数の欄は 2 つずつにまとめられています: そのまとまりが重要な境界に揃うので、数えずにニブルやバイトを画面から読み取れます。

負の数と 2 の補数

負の数はそれ自体では 2 進数の形を持ちません。レジスタにマイナス記号はなく — ビットだけです — ので、符号はビット自体に符号化されねばならず、それにはビットが何個あるかを決める必要があります。だからビット幅の選択が存在し、変えると答えが変わるのです。

すべての現代のマシンが使う方式は 2 の補数です: 負の数を表すには、その正の形を取り、すべてのビットを反転し、1 を足します。結果として最上位ビットが「負」を意味することになり、符号のための特別な場合なしにふつうの足し算が働き続けます。

0000 0101   # 5
1111 1010   # すべてのビットを反転
1111 1011   # 1 を足す: バイトとしての -5、16 進数では fb

レジスタを広げると同じ数が別のパターンを得ます: -5 は 8 ビットで fb、16 ビットで fffb、32 ビットで fffffffb です。値は変わっていません。それを運ぶビットの数が変わったのです。このツールで幅を切り替えると、まさにそれが見えます。

なぜ 0xFF は 255 でもあり -1 でもあるのか

ビット ff は、それが符号付きかどうかを言いません。1111 1111 を保持するバイトは、それを読み込むコードが符号なしの型を宣言していれば 255 と、符号付きを宣言していれば -1 と読まれます。バイト自体には両者を区別するものは何もありません — 型は、そのような情報を持たないビットについてプログラムが行う主張です。

それが本物のバグの一族の源です: 負になるチェックサム、ファイルから読んだバイトがゼロ未満として比較される、符号の有無が実装依存なので ARM で x86 と違う振る舞いをする C の char です。符号付きと符号なしの読みが異なるときはいつでも、このツールは両方を示します。その食い違いこそ、たいていあなたが探していたものだからです。

ビットのグリッド

現在の値のすべてのビットが位置番号とともに示され、1 つをクリックすると反転します。基数がただちに更新され、いくつかの問いを手で行うよりずっと答えやすくします:

  • このフラグ値でどのビットが立っているか — クリックして通り抜け、位置を読みます。
  • ビット 4 と 7 のマスクは何か — その 2 つを立てて 16 進数を読みます。
  • 最上位ビットを立てると符号付きの値に何が起きるか — 目に見えて負になります。
  • この値は 2 の累乗か — 2 の累乗はちょうど 1 ビットだけが立っています。

ビット 0 は最下位ビットで右にあり、これは普遍的な慣習で、右から左のページでもグリッドが左から右のままである理由です。行は 8 ビット幅なので、バイトの境界がひと目で見えます。

大きな数も正確なまま

JavaScript の数は倍精度で、整数を正確に保持するのは 2^53 — 約 9000 兆 — までです。64 ビットの値はそれを超えることがあり、ふつうの数で作られた変換器はそれを黙って丸め、もっともらしく見えて最後の桁が誤った 16 進数の文字列を生みます。

ここではすべてが代わりに任意精度の整数を使うので、完全な 64 ビットの値が正確に変換されます。任意精度のビット幅モードはさらに進んで上限を完全に取り除きます — 暗号の値や大きな識別子に有用です — が、固定のビット幅がなければ 2 の補数もないので、そのモードでの負の数はどの基数でも単にマイナス記号を持つことに注意してください。

2 進数から 10 進数へ、10 進数から 2 進数へ

2 進数と 10 進数は、ここで唯一まったく共通点のない組です: 2 は 10 の累乗ではなく、10 も 2 の累乗ではないので、どちらの向きも参照では済まず、両方とも本物の計算が要ります。しかもそれは同じ計算ではありません。めったに口にされない部分ですが、片方向の速い手計算は、戻る向きの速い手計算の逆ではないのです。

  • 2 進数から 10 進数へ、倍にする方法: いちばん左のビットでゼロから始め、ビットごとに手元の値を 2 倍してそのビットを足します。1011 なら 1、2、5、11 と進みます — 一度の走査で、位の重みを覚える必要はなく、このツールが入力を読むときに行っているのもまさにこれです。
  • 2 進数から 10 進数へ、位で足す方法: 立っているビットの位の重みを足し合わせます。上の詳しい例がそれです。立っているビットが 2 つか 3 つのときは速く、ほとんどが立っているときは遅くなります。
  • 10 進数から 2 進数へ、割る方法: 2 で割って余りを書き、何も残らなくなるまで繰り返し、余りを下から上へ読みます。答えは最下位ビットから先に出てくるので、書いている間じゅう逆さまに見えます。
  • 10 進数から 2 進数へ、引く方法: 収まる最大の 2 の累乗を引き、繰り返します。200 は 128 を失って 72 が残り、72 は 64 を失って 8 が残り、8 は 8 を失って何も残りません — つまり位置 7、6、3 のビットが立ち、バイトは 1100 1000 です。立つビットが少ないときは割るより速くなります。

ここのどの手計算も扱えないことが一つあります: 負の 10 進数は、ビット幅を選ぶまで 2 進数の形をまったく持ちません。マイナス 5 を 2 進数で、と尋ねられたときの正直な答えは、何ビットですか、という問い返しです。それを決めるのがビット幅の選択で、上の 2 の補数の節が扱っているのもそれです。任意精度モードには幅がないので、マイナス記号がそのままどの基数にも付いてきます。

10 進数から 16 進数へ、16 進数から 10 進数へ

これを頻繁にやる人は、まず 16 で割りません。16 進数と 2 進数の関係こそが近道です: 10 進数を一度 2 進数に直し、ビットを右から 4 つずつに切り、各まとまりを 16 進数 1 桁として読みます。戻るときは同じ道を逆にたどり、各 16 進数の桁をその 4 ビットに展開して、立っているビットの重みを足します。1 バイトまでならもっと短い道もあります: 16 進数の 1 桁目は 2 桁目の 16 倍なので、掛けて足すだけです。

  • 255 は ff — すべてのビットが立ったバイトです。暗記する価値があるのはこれで、そこがバイトの終わりだからです。
  • 256 は 100 です。満杯のバイトから一歩進むと、10 進数で 99 が 100 に繰り上がるのとまったく同じように桁が繰り上がり、16 進数の数はバイトに収まらない桁を得ます。
  • 65535 は ffff、65536 は 10000 — 1 バイト上の同じ二つの目印で、そこが 16 ビットのカウンタの終わりです。
  • 4096 は 1000 です。だからページサイズやアラインメントやメモリのオフセットは、16 進数では丸く 10 進数ではぎざぎざに見えます。16 進数は 4 ビットずつ数え、ハードウェアもそう数えるからです。

大文字と小文字は区別されません: FF と ff は同じ値で、このツールは入力ではどちらも受け付け、出力では小文字を書きます。しないのは推測です。接頭辞 0x は 16 進数の欄のもので、10 進数の欄では黙って捨てられるのではなく拒否されます。誤った基数で読まれた値は、変換器が決してもっともらしく見せてはならない唯一の誤りだからです。

8 進数から 10 進数へ、そして答えを変える先頭のゼロ

8 進数がほかのどこよりも生き残っているのはファイルの権限です。ユーザーのグループごとの 3 つの権限ビットが、ちょうど 8 進数 1 桁に収まるからです。10 進数への変換は 8 の累乗による素直な位取りの計算で、8 進数の 755 は 64 が 7 つと 8 が 5 つと 5、つまり 493 です。逆向きは 8 で割って余りを下から上へ読む形で、10 進数から 2 進数への変換と同じ形、同じ理由です: 8 にも 10 との関係はありません。

  • 755 は 10 進数で 493、644 は 420、777 は 511 です。これらの 10 進数はどれも誰の役にも立ちませんが、それが要点です — 権限が 8 進数で書かれるのは、桁が権限ビットに揃うからであって、値が何かを数えているからではありません。
  • 先頭のゼロは C と Python 2 では基数の印です: そこでは 0755 は 8 進数、すなわち 493 です。Python 3 はその書き方をきっぱり拒み、代わりに 0o755 を求めます。それが静かなバグの一族をまるごと取り除きました。
  • YAML 1.1 も引用符のない 0755 を 493 と読みます。だから設定ファイルの権限モードは引用符で囲む必要があり、そうしないと書いたはずのモードでなくなります。
  • JSON は最初から許していません。その文法が数の先頭のゼロを禁じているので、0755 はそこでは数ですらなく構文エラーです — 三つのうちいちばん大きな声で、唯一読み違えようのない振る舞いです。

このツールは先頭のゼロを何の印とも見なしません。基数を決めるのは入力する欄で、0755 は 10 進数の欄では 755、8 進数の欄では 493 です。接頭辞 0o は 8 進数の欄で受け付けられ、ほかのどこでも拒否されます。接頭辞から基数を推測することは、入力された数とは別の数を返すことを意味するからです。

8 進数から 16 進数へ: 近道のない組

どちらも 2 の累乗なので、どちらも同じビットの組み直しにすぎません。それでもこれは、四つの基数の中で唯一、桁と桁を対応させる規則がまったくない組です。8 進数 1 桁は 3 ビット、16 進数 1 桁は 4 ビットで、三と四はどちらも他方で割り切れないので、境界は決して揃いません。ビットを書き出して組み直す以外に道はありません。

  • 8 進数の各桁を、順にその 3 ビットで書きます: 755 は 111 101 101 になります。
  • そのビットを右端から 4 つずつに組み直し、割り切れないときは左をゼロで埋めます: 0001 1110 1101。
  • 4 つずつのまとまりを 16 進数 1 桁として読みます: 1ed。埋める端を間違えるのがここでの古典的な誤りで、しかも誤って見えません — 黙って答えを何倍かにするだけです。

16 進数 2 桁がちょうど 1 バイトで、8 進数 2 桁はそうでないことが、メモリを読むうえで 16 進数が 8 進数を押しのけた理由のすべてです: 8 ビットは 8 進数 2 桁と 3 分の 2 なので、バイトの境界が桁の途中に落ちます。8 進数は語長が 3 ビットの倍数だった機械に合い、16 進数は 8 ビットのバイトに合います。そしてこのページでは、この組にはビットのグリッドがどちらの手計算より速いのです — ビットを一度立てれば、両方の欄がすでに答えを示しています。

よくある質問

-5 が 2 進数で -101 ではなく fb と表示されるのはなぜですか?
レジスタにマイナス記号がないからです。幅を選ぶと、負の数は 2 の補数で示され、これはマシンが実際に保存するものです: バイトでの -5 は 1111 1011、すなわち fb です。符号付きの数学的な形が欲しければ、幅を任意精度に切り替えてください。
0xFF は 255 ですか -1 ですか?
両方です — ビットは同一で、宣言された型だけが決めます。符号付き 8 ビットの値は ff を -1 と読み、符号なしは 255 と読みます。2 つの読みが異なるときはいつでも、このツールはそれらを並べて示します。
10 進数の代わりに 16 進数がこれほど使われるのはなぜですか?
1 桁の 16 進数がちょうど 4 ビットなので、16 進数と 2 進数は計算なしの参照で変換でき、桁がバイトの境界に揃うからです。10 進数は 2 進数とそのような関係を持たないので、10 進数の値はどのビットが立っているかについて何も教えません。
ここでの最大の基数は何で、なぜ 36 ですか?
36 です。10 個の数字に 26 個の文字 — 素のラテンアルファベットが提供するすべての記号 — だからです。それより高くすると、どの追加の文字を使うかの取り決めが要りますが、単一の合意されたものはありません。
0x や空白を含む値を貼り付けられますか?
はい。0x、0b、0o の接頭辞は対応する基数で受け付けられ、空白とアンダースコアは無視されるので、コードやデータシートからそのまま貼り付けても、先に整える必要はありません。
64 ビットの値は正確に変換されますか?
はい。すべての計算が任意精度の整数を使うので、2^53 — ふつうの JavaScript の数が丸め始めるところ — を超えた値も正確なまま保たれます。
入力した内容はサーバーに送られますか?
いいえ。ブラウザ内での計算です。何もアップロードも記録もされず、ネットワーク接続なしで動きます。
2 進数を手で 10 進数に変換するにはどうしますか?
左から倍にして足します: ゼロから始め、ビットごとにそれまでの値を 2 倍してそのビットを足します。1011 なら 1、次に 2、次に 5、次に 11 です。一度の走査で位の重みを覚える必要はなく、同じ方法はどの基数でも使えます — 倍にする代わりに基数を掛けてください。
255 は 16 進数でいくつで、なぜこの数がよく出てくるのですか?
ff です。8 ビットすべてが立ったバイトなので、1 バイトが保持できる最大の値であり、数え上げが 2 バイト目へ繰り上がる地点です。だから色のチャンネルやマスクやサイズの上限のいたるところに出てきます。それより 1 大きい 256 は、16 進数では 100 と書きます。
0755 は 755 と同じ数ですか?
ここでは 10 進数の欄なら同じ、8 進数の欄なら違います: 基数を決めるのは欄で、先頭のゼロはただのゼロの桁です。ほかでは言語によります — C と Python 2 は 0755 を 8 進数、すなわち 493 と読み、Python 3 はその書き方を拒んで 0o755 を求め、YAML 1.1 は 493 と読み、JSON は構文エラーとして扱います。
8 進数を 16 進数に変換するにはどうしますか?
2 進数を経由します。それより短い道はないからです: 8 進数 1 桁につき 3 ビット、16 進数 1 桁につき 4 ビットで、両者は決して揃いません。8 進数の各桁をその 3 ビットに展開し、全体を右から 4 つずつに組み直し、4 つずつを 16 進数 1 桁として読みます — 755 は 111 101 101 になり、次に 0001 1110 1101、そして 1ed です。

関連するツール

  • データ容量変換

    同じ数を、ビットの並びではなくデータの量として読むとどうなるか。あちらのページはバイト数を KB・MB・GB と KiB・MiB・GiB に並べて変換し、2 つの系がどこで食い違うかも示します。

  • パーセント計算機

    基数は数の書き方を、パーセントは別の数と比べた大きさを表します。あちらのページは割合・変化・逆算を計算し、あなたの数字を入れた式も並べて出します。