n進数の変換(2進・8進・16進)
| 進数 | 値 |
|---|---|
| 2進数コンピュータの内部表現 | 1111 1111 |
| 8進数ファイルの権限(chmod) | 377 |
| 10進数 | 255 |
| 16進数色コード・メモリアドレス | ff |
| 36進数0-9 と a-z を使い切る上限 | 73 |
2の補数で見る
「0xFF は 255 なのか −1 なのか」は、何ビットの符号つきとして読むかで変わります。
| 符号なしunsigned 8bit | 255 |
|---|---|
| 符号つきsigned 8bit・2の補数 | 範囲外 |
| 同じビットの並び16進 / 2進 | 0xff 1111 1111 |
よくある質問
0xFF は 255 ですか、それとも −1 ですか?
どちらもありえます。符号なし8ビットとして読めば255、符号つき8ビット(2の補数)として読めば−1です。同じビットの並びをどう解釈するかの違いなので、扱っている型がどちらかを確認する必要があります。
2の補数とは何ですか?
負の数をビットで表す方法です。ある数の全ビットを反転して1を足すと、その数の負の値になります。この方式だと引き算を足し算の回路で処理でき、0の表現が1通りに定まるという利点があります。
16進数はなぜ使われるのですか?
1桁がちょうど4ビットに対応するからです。8ビットが2桁、32ビットが8桁ときれいに収まり、2進数の長い並びを短く書けます。色コード #FF8800 も、赤・緑・青を各1バイトずつ表しています。
8進数はどこで使いますか?
ファイルの権限を表す chmod 755 のような場面です。読み・書き・実行の3つのビットが1桁にちょうど収まるため、3桁で所有者・グループ・その他の権限を表せます。
36進数まで対応しているのはなぜですか?
0〜9の10文字とa〜zの26文字を合わせて36文字が、英数字だけで表せる上限だからです。短いURLやIDの生成で使われます。
0x とは何ですか?
16進数であることを示す接頭辞です。C 言語の規格(ISO/IEC 9899 第6.4.4.1節)が「16進定数は接頭辞 0x または 0X に続けて書く」と定めています。同じ節では、先頭が 0 で続きが 0〜7 だけの数は8進定数です。この計算機では、基数に 16 を選んだときだけ 0x を接頭辞として外します。
010 は 8 ですか、10 ですか?
どちらにもなります。C 言語の規格では先頭の 0 が8進の接頭辞なので、C のソースに書いた 010 は8進で、値は 8 です。この計算機は選んだ基数どおりに読むので、10進数を選べば 10、8進を選べば 8 になります。
2〜36進数を相互に変換します。負の数と2の補数にも対応しています。
2の補数はなぜあの形なのか
負の数をビットで表す方法は、2の補数のほかにもあります。先頭1ビットを符号に使う 「符号つき絶対値」や、全ビットを反転する「1の補数」です。どちらも直感的ですが、 0が2通り(+0と−0)できてしまい、足し算の回路が複雑になります。
2の補数では、負の数を「2のビット幅乗から引いた値」として表します。 8ビットなら −1 は 256 − 1 = 255、つまり 0xFF です。この方式の利点は、 引き算を「負の数の足し算」としてそのまま処理できる点にあります。 1 + (−1) を計算すると 0x01 + 0xFF = 0x100 になり、8ビットからあふれた桁を捨てると 0x00 になります。特別な処理を入れずに正しい答えが出ます。
0も1通りしかありません。0x00 だけが0で、−0 に相当するビット列は存在しません。 この2点のために、現在のほぼすべてのコンピュータが2の補数を採用しています。
範囲外の値を切り捨てない理由
8ビットの符号つきで表せるのは −128 から 127 までです。ここに128を入れると、 多くのプログラミング言語ではあふれた桁が捨てられて −128 になります。 この計算機では、そうならずに「範囲外です」と表示します。
黙って切り捨てた値を出すと、入力を間違えたことに気づけないまま 別の数を答えとして受け取ってしまうためです。あふれ自体を調べたい場合は、 ビット幅を大きくするか、符号なしの表として読んでください。
0x と先頭の 0 は、C 言語の規格が決めた接頭辞
16進数の前に付く 0x は、C 言語の規格(ISO/IEC 9899)の第6.4.4.1節が「16進定数は接頭辞 0x または 0X に続けて、0〜9 と a〜f(A〜F)を並べる」と定めている書き方です。 同じ節に「8進定数は接頭辞 0 に続けて 0〜7 だけを並べる」ともあり、C では 010 が 8 進で、値は 8 になります。 桁を揃えるつもりの 0 が別の数として読まれるので、この計算機は選んだ基数と一致する接頭辞だけを外します。 16進を選んで 0b1010 と入れれば、b は 16 進の数字(11)として読みます。
| ビット幅 | 16進の桁数 | 最大値(16進) |
|---|---|---|
| 8 ビット | 2 桁 | FF |
| 16 ビット | 4 桁 | FFFF |
| 32 ビット | 8 桁 | FFFF FFFF |
| 64 ビット | 16 桁 | FFFF FFFF FFFF FFFF |
色コード #RRGGBB が 16 進なのは、1 色が 1 バイトだから
CSS の色 #ff8800 は、W3C の CSS Color Module Level 4 が「最初の 2 桁を 16 進数として読んだ値が赤の成分で、00 が最小、ff(10 進で 255)が最大。次の 2 桁が緑、最後の 2 桁が青」と定義しています。 赤・緑・青がそれぞれ 0〜255 の 1 バイトなので 16 進 2 桁にぴったり収まり、3 色で 6 桁になります。 同じ仕様は 8 桁の形も定めていて、最後の 2 桁が不透明度です。
出どころ: C 言語の規格の草稿 N1256(ISO/IEC 9899:TC3)(新しいタブで開きます)の第6.4.4.1節と CSS Color Module Level 4「The RGB hexadecimal notations」(新しいタブで開きます)の原文。