有时我会看到以十六进制定义的整数常量,而不是十进制数。这是我从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
显然更简单,那么可能会有一些性能提升吗?我一点也不这么认为,从那以后改编它应该是编译器的工作。
答案 0 :(得分:61)
这可能是组织和视觉上的清洁。基数16与二进制10的关系比基数10简单得多,因为在基数16中,每个数字恰好对应于4位。
注意上面的常量如何将常量分组为多个数字。如果它们以十进制表示,则共同的位将不太清楚。如果它们具有共同的十进制数字,则位模式将不具有相同的相似度。
此外,在许多情况下,希望能够一起按位OR运算以创建标志组合。如果每个常量的值被约束为仅具有非零的位的子集,则可以以可以重新分离的方式来完成。使用十六进制常量可以清楚地表明每个值中的哪些位非零。
还有另外两种合理的可能性:八进制或基数8只能编码每位3位。然后是二进制编码的十进制,其中每个数字需要四位,但禁止高于9的数字值 - 这将是不利的,因为它不能代表二进制可以的所有可能性。
答案 1 :(得分:25)
“定义2914而不是0x0B62”
显然更简单我不知道具体案例,但通常情况并非如此。
中有两个问题:
0x0B62(长度为4个十六进制数字,因此它代表一个16位数字)
- >
0000101101100010
(我敢于你用2914做同样的事。)
这是使用十六进制值的一个原因,另一个原因是值的来源可能使用十六进制(例如规范的标准)。
有时我发现它很愚蠢,如:
public static final int NUMBER_OF_TIMES_TO_ASK_FOR_CONFIRMATION = ...;
用十六进制写几乎总是很傻,我敢肯定在某些情况下它不会。
答案 2 :(得分:9)
例如,应用十六进制masks时的可读性。
答案 3 :(得分: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;
对于十进制数字,人们很难在大量不同但相关的项目中“注意”位的常量区域。
答案 4 :(得分:6)
您是想写0xFFFFFFFF
还是4294967295
?
第一个更清楚地表示具有全部的32位数据类型。当然,许多经验丰富的程序员会认识到后一种模式,并且怀疑其真正的含义。但即使在这种情况下,它也更容易出现输入错误等。
答案 5 :(得分:5)
当谈到大数字时,用十六进制表示它们会使它们更具可读性,因为它们更紧凑。
此外,有时对于二进制转换很重要:十六进制数可以很容易地转换为二进制。有些程序员喜欢这样做,这对数字进行位操作很有帮助。
至于表现收益:不,没有。
答案 6 :(得分:3)
十六进制是最接近二进制格式的可读格式。这简化了很多位操作,例如
答案 7 :(得分:3)
0xB62等于2914 :-)
对于开发人员来说,当用十六进制表示常量的位模式比将其表示为基数为10的整数时,更容易对其进行精神描绘。
这个事实使十六进制的表示更适合API中使用的常量,其中位和它们的位置(例如用作单独的标志)是相关的。
答案 8 :(得分:3)
啊,但是0xDECAFF既是素数(1460959),又是紫色(RGB)。
对于颜色,十六进制更方便。
FF FF FF为白色 00 00 FF为蓝色 FF 00 00为红色 00 FF 00为绿色 很容易将颜色关系视为数字(虽然人眼的伽马和保真度往往会让人失望,但我们会忽略那些不方便的物理事实,以获得纯粹的数学精确度!
答案 9 :(得分:2)
没有性能提升。
但是,如果这些常量对应于下面的某些位,那么大多数程序员更喜欢使用Hex(甚至二进制)来使其更清晰,更易读。
例如,可以很容易地看到GL_EXP2有2位,1位和0x0800位(小数为2048)。小数值2049不太清楚。
答案 10 :(得分:1)
有时使用与位相关的算法会更容易。其他时候,它处理比特比较,正如我在评论中的陈述,4位(二进制数字)转换为1个十六进制字母,因此,A3 = 10100011。
其他时候,它既有趣又打破单调,但不熟悉十六进制的人可能会认为你是用指针做事
int data = 0xF00D;
if ( val != 0xC0FFEE )
{
data = 0xDECAF;
}
我有时会用它来检查像int这样的东西。例如,您可以使用0x7FFFFFFF(0x80000000在许多情况下工作,但0x7F ...更安全)来获得最大int界限。如果你没有像MAX_INT这样的语言,那么设置一个非常高的误差常数很方便。该技术也可以扩展,因为对于64位,您可以使用0x7FFFFFFFFFFFFFFF。您可能会注意到Android使用0x7_ __ 进行R.id表查找。
我打赌他们是为了清晰起见而这样做的。你可以很容易地使用整数,但如果你熟悉十六进制,那就不错了。看起来他们正在为某些功能保留x值。在十进制中,你会做一些像0-99这样的错误,100-199用于别的东西,等等。他们如何做到这一点的方式不同。
在性能方面,你在运行时什么也得不到,因为编译器(甚至很多汇编器)最终将任何格式转换为二进制,无论是十进制,八进制,十六进制,浮点数,双精度等等。