2.2.4 十六进制计数系统
前面提到,二进制数值的表示形式很冗长。而十六进制表示形式有两个非常重要的特性:一,十六进制表示形式非常紧凑;二,十六进制数值和二进制数值的相互转换非常简单。因此,为了让程序更容易理解,软件工程师通常使用十六进制表示形式。
因为十六进制表示形式的基数是16,所以十六进制小数点左侧的每个数字代表的值为该数字乘以16的幂,指数按位递增。例如,数字123416等于:
1×163+2×162+3×161+0×160
即
4096+512+48+4
即
20210
十六进制表示形式使用字母A~F表示10个标准十进制数字(0~9)以外的6个数字。下面都是合法的十六进制数值:
23416 DEAD16 BEEF16 0AFB16 FEED16 DEAF16
1.编程语言的十六进制数值表示
十六进制表示形式存在一个问题:它(如“DEAD”)容易和标准的程序标识符混淆。因此,编程语言中的十六进制数值大多会加上特殊的前缀或后缀字符。下面列出了几种流行的编程语言的十六进制字面值常量写法:
●C、C++、C#、Java、Swift及其他C衍生编程语言使用前缀0x。十六进制数值DEAD16用字符串0xdead表示。
●MASM汇编程序使用后缀h或H。但这不能完全避免标识符和十六进制字面值常量之间的歧义(例如,“deadh”看起来仍然很像MASM的标识符),所以十六进制值还要以数字开头。在数值开头加上0(因为前缀0不会改变数字表示的数值)得到0deadh,这样表示DEAD16就不会产生歧义了。
●Visual Basic使用前缀&H或&h。前面的例子DEAD16在Visual Basic中表示为&Hdead。
●Pascal(Delphi)使用前缀$。在Delphi/Free Pascal中DEAD16被表示为$dead。
●HLA也使用前缀$,并且可以像在二进制中那样在十六进制数字中插入下画线,使数值更容易阅读(例如,$FDEC_A012)。
本书在多数情况下都采用HLA/Delphi/Free Pascal的十六进制表示方法,除非示例使用了其他编程语言。例如,本书中也有一些C/C++示例,因此我们也会经常看到C/C++表示方法。
2.十六进制和二进制表示形式之间的相互转换
二进制表示形式和十六进制表示形式之间的相互转换非常简单,这是十六进制表示形式流行的一个原因。只要记住表2-1中的简单规则即可。
表2-1 二进制和十六进制表示形式转换表
将十六进制数值中的每个数字替换成表中对应的四位二进制数字,就可以转换成二进制表示形式。例如,将$ABCD中的每个十六进制数字转换成表2-1中对应的二进制数字就完成了到二进制格式%1010_1011_1100_1101的转换:
将二进制表示形式转换为十六进制一样简单。首先,确保二进制数值的位数是4的倍数,位数不足则在左边补0。例如,二进制数值1011001010,在左边补两位0就可以变为12位,但数值并不会发生改变:001011001010。然后,将二进制数值分成四位一组:0010_1100_1010。最后,在表2-1中找到这些二进制数字,替换成对应的十六进制数字:$2CA。显而易见,这比从十进制到二进制的转换或十进制到十六进制的转换简单多了。