为什么要使用十六进制常量?

use*_*572 55 java opengl hex decimal

有时我看到以十六进制定义的整数常量,而不是十进制数.这是我从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;
Run Code Online (Sandbox Code Playgroud)

这显然更简单的定义2914来代替0x0B62,所以有可能有些性能提升?我认为不这么认为,从那时起编译器应该改变它.

Chr*_*ton 63

这可能是组织和视觉上的清洁.基数16具有比二进制10更简单的二进制关系,因为在基数16中,每个数字恰好对应于四位.

请注意,在上面的常量中,常量被分组为多个数字.如果它们以十进制表示,则共同的位将不太清楚.如果它们具有共同的十进制数字,则位模式将不具有相同的相似度.

而且,在许多情况下,希望能够一起按位OR运算以创建标志的组合.如果每个常量的值被约束为仅具有非零的位的子集,则可以以可以重新分离的方式来完成.使用十六进制常量可以清楚地表明每个值中的哪些位非零.

还有另外两种合理的可能性:八进制或基数8只能编码每位3位.然后是二进制编码的十进制,其中每个数字需要四位,但禁止高于9的数字值 - 这将是不利的,因为它不能代表二进制可以的所有可能性.

  • 您将常量与按位或相结合是非常正确的......完全忘记了那个...... (2认同)

ese*_*sej 26

"定义2914而不是0x0B62显然更简单"

我不知道具体的情况,但通常情况并非如此.

在这两个问题中:

  • A)2914的比特值是多少?
  • B)0x0B62的位值是多少?

很多开发者会更快地更准确地回答B. (这也适用于类似的问题)


0x0B62(长度为4个十六进制数字,因此它代表一个16位数字)

  • 0 = 0000的位
  • B = 1011的位
  • 比特6 = 0110
  • 比特2 = 0010

- >

0000101101100010

(我敢跟2914这样做.)


这是使用十六进制值的一个原因,另一个原因是值的来源可能使用十六进制(例如规范的标准).

有时我发现它很愚蠢,如:

public static final int NUMBER_OF_TIMES_TO_ASK_FOR_CONFIRMATION = ...;
Run Code Online (Sandbox Code Playgroud)

用十六进制写几乎总是很傻,我敢肯定在某些情况下它不会.

  • 对不起,我的观点不够明确.上面的"计算"几乎是由我和其他人立即完成的 - 我们经常在将值粘贴到您的计算器之前完成.我经常发现自己只对一位(一个标志)感兴趣,所以我不扫描整个字符串只是找到覆盖该位的字节/数字. (9认同)
  • @esej:为了使事情更清楚,比较找到0x60000000与1610612736的位模式的难度.如果两个数字都有很多非零的非F数字,难度的差异不是那么明显,但很多实际十六进制值的大部分由零和F组成. (4认同)

Ale*_*eon 9

例如,应用十六进制掩码时的可读性.


Edw*_*uck 8

十进制数和十六进制数之间不会有性能增益,因为代码将被编译为移动表示数字的字节常量.

计算机不做小数,它们(最多)做二进制.十六进制非常干净地映射到二进制,但是需要一些工作才能将十进制数转换为二进制数.

当你有许多相关的项目时,十六进制闪耀的地方,其中许多是相似的,但略有不同.

// 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;
Run Code Online (Sandbox Code Playgroud)

对于十进制数字,人们很难在大量不同但相关的项目中"注意"位的恒定区域.


tsk*_*zzy 6

你愿意写0xFFFFFFFF还是4294967295

第一个更清楚地表示具有全部的32位数据类型.当然,许多经验丰富的程序员会认识到后一种模式,并且怀疑其真正的含义.但即使在这种情况下,它也更容易出现输入错误等.


Rad*_*zea 5

当谈到大数字时,用十六进制表示它们会使它们更具可读性,因为它们更紧凑.

此外,有时对于二进制转换很重要:十六进制数可以很容易地转换为二进制.一些程序员喜欢这样做,它有助于对数字进行位操作.

至于性能增益:不,没有.