web-dev-qa-db-ja.com

16進定数を使用する理由

時々、10進数ではなく16進数で定義された整数定数が表示されます。これは私がGL10クラスから取った小さな部分です:

public static final int GL_STACK_UNDERFLOW = 0x0504;
public static final int GL_OUT_OF_MEMORY = 0x0505;
public static final int GL_EXP = 0x0800;
public static final int GL_EXP2 = 0x0801;
public static final int GL_FOG_DENSITY = 0x0B62;
public static final int GL_FOG_START = 0x0B63;
public static final int GL_FOG_END = 0x0B64;
public static final int GL_FOG_MODE = 0x0B65;

2914の代わりに0x0B62を定義する方が明らかに簡単なので、パフォーマンスが向上する可能性はありますか?それを変更するのはコンパイラの仕事であるべきだから、私はそうは思わない。

53
user717572

組織的および視覚的な清浄度が高い可能性があります。基数16では、各桁が正確に4ビットに対応しているため、基数16は基数10よりもバイナリとの関係がはるかに単純です。

上記で、定数が共通の多くの数字でグループ化されていることに注意してください。それらが10進数で表されている場合、共通のビットはあまり明確ではありません。代わりに10進数字が共通している場合、ビットパターンの類似度は同じではありません。

また、多くの場合、フラグの組み合わせを作成するために定数をビットごとにORで結合できることが望まれます。各定数の値がゼロ以外のビットのサブセットのみを持つように制限されている場合、これは再分離できる方法で実行できます。 16進定数を使用すると、各値でどのビットが非ゼロであるかが明確になります。

他にも2つの妥当な可能性があります。8進数、または基数8は1桁あたり3ビットを単純にエンコードします。そして、各桁に4ビットが必要な2進化10進数がありますが、9を超える数字は禁止されています。これは、2進数で可能なすべての可能性を表すことができないため不利です。

62
Chris Stratton

「0x0B62の代わりに2914を定義する方が明らかに簡単です」

私はその特定のケースについては知りませんが、それはしばしば真実ではありません。

2つの質問のうち:

  • A)2914のビット値は何ですか?
  • B)0x0B62のビット値は何ですか?

Bは、多くの開発者によってより速くより正確に回答されます。 (これは同様の質問にも当てはまります)


0x0B62(4桁の16進数であるため、16ビットの数値を表します)

  • 0 = 0000のビット
  • bのビット= 1011
  • 6 = 0110のビット
  • 2 = 0010のビット

->

0000101101100010

(2914でも同じことをしてみてください。)


これが16進値を使用する理由の1つであり、別の理由は、値のソースが16進を使用する可能性があることです(たとえば、仕様の標準)。

時々私はそれを愚かに見つけます:

public static final int NUMBER_OF_TIMES_TO_ASK_FOR_CONFIRMATION = ...;

ほとんどの場合、16進数で書くのはばかげていますが、そうでない場合もあるでしょう。

26
esej

16進数 マスク を適用する場合の読みやすさ。

9
Alexis Pigeon

コードは数値を表すバイト定数を移動するようにコンパイルされるため、10進数と16進数の間にパフォーマンスの向上はありません。

コンピューターは10進数ではなく、(せいぜい)バイナリーを実行します。 16進数は2進数に非常にきれいにマッピングされますが、10進数を2進数に変換するには少し作業が必要です。

16進数が輝く場所の1つは、多くの関連アイテムがあり、その多くが類似しているがわずかに異なる場合です。

// These error flags tend to indicate that error flags probably
// all start with 0x05..
public static final int GL_STACK_UNDERFLOW = 0x0504;
public static final int GL_OUT_OF_MEMORY = 0x0505;

// These EXP flags tend to indicate that EXP flags probably
// all start with 0x08..
public static final int GL_EXP = 0x0800;
public static final int GL_EXP2 = 0x0801;

// These FOG flags tend to indicate that FOG flags probably
// all start with 0x0B.., or maybe 0x0B^.
public static final int GL_FOG_DENSITY = 0x0B62;
public static final int GL_FOG_START = 0x0B63;
public static final int GL_FOG_END = 0x0B64;
public static final int GL_FOG_MODE = 0x0B65;

10進数の場合、多数の異なるが関連する項目にわたってビットの一定領域を「通知」するのは難しいでしょう。

8
Edwin Buck

むしろ0xFFFFFFFFまたは4294967295

最初のものは、すべて1の32ビットデータ型をより明確に表しています。もちろん、多くのベテランプログラマーは後者のパターンを認識し、それが本当の意味であることをこっそりと疑っています。ただし、その場合でも、入力ミスなどが発生しやすくなります。

6
tskuzzy

大きな数になると、16進数で表すと読みやすくなります。これは、それらがよりコンパクトだからです。

また、バイナリへの変換にとって重要な場合もあります。16進数は非常に簡単にバイナリに変換できます。一部のプログラマーはこれを行うことを好むため、数値に対してビット演算を行うときに役立ちます。

パフォーマンスの向上に関しては、いいえ、ありません。

5
Radu Murzea

16進数は、バイナリ形式に最も近い読み取り可能な形式です。これにより、たとえば、多くのビット操作が簡素化されます

3
GETah

0xB62は2914に等しい:-)

開発者にとって、定数を16進数で表すと、10進法の整数として表すよりも、定数のビットパターンを簡単に想像することができます。

この事実により、ビットとその位置(たとえば、個別のフラグとして使用される)が関連するAPIで使用される定数により適した16進数での表示が可能になります。

3
rsp

Ahh but 0xDECAFFは両方とも素数(1460959)であり、満足のいく紫色(RGB)です。

色については、16進数の方がはるかに便利です。

FF FF FFは白00 00 FFは青FF 00 00は赤00 FF 00は緑純粋な数学的精度のためのこれらの不便な物理的事実!

3
ggb667

パフォーマンスの向上はありません。

ただし、これらの定数が下の特定のビットに対応する場合、ほとんどのプログラマーは、16進数(またはバイナリー)を好んで、それを明確で読みやすくします。

たとえば、GL_EXP2には2ビット、1ビット、および0x0800ビット(10進数で2048)があることが簡単にわかります。 2049の10進数値はあまり明確ではありません。

2
user949300

ビット関連のアルゴリズムを使用する方が簡単な場合があります。それ以外の場合、ビット比較を扱います。コメント内の私のステートメントでは、4ビット(2進数)が1つの16進文字に変換されるため、A3 = 10100011です。

他の場合、それは楽しいか、単調さを破りますが、ヘックスに慣れていない人は、あなたがポインタで物事をしていると思うかもしれません

int data = 0xF00D;
if ( val != 0xC0FFEE )
{
   data = 0xDECAF;
}

私は時々intのようなものの境界をチェックするためにそれを使用します。たとえば、0x7FFFFFFF(多くの場合0x80000000は機能しますが、0x7F ...の方が安全です)を使用して、最大int境界を取得できます。 MAX_INTなどの言語を持つ言語がない場合、非常に高いエラー定数を設定するのに便利です。 64ビットの場合は0x7FFFFFFFFFFFFFFFを使用できるため、この手法も同様にスケーリングします。 Android=は0x7 ___をR.idテーブルのルックアップに使用します。

私は彼らが明快さのためにそれをしているに違いない。整数は簡単に使用できますが、16進数に精通していれば悪くありません。特定の関数に対してx値を予約しているようです。 10進数では、0から99はエラー、100から199はエラーなどのようになります。彼らがどのようにそれを行っているかは、異なる方法でスケーリングされます。

コンパイラー(多くのアセンブラーでも)が最終的に10進数、8進数、16進数、浮動小数点数、倍精度などのバイナリーに変換するため、パフォーマンスに関しては、実行時に何も得られません。

1
Joe Plante