基数変換ツール

数値を 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 の補数もないので、そのモードでの負の数はどの基数でも単にマイナス記号を持つことに注意してください。

よくある質問

-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 の数が丸め始めるところ — を超えた値も正確なまま保たれます。
入力した内容はサーバーに送られますか?
いいえ。ブラウザ内での計算です。何もアップロードも記録もされず、ネットワーク接続なしで動きます。