《深入理解计算机系统》之进制间转换

327 阅读3分钟

十六进制表示法

  一个字节由8位组成。在二进制表示法中,它的值域是00000000200000000_211111111211111111_2。如果是十进制整数,它的值域是010255100_{10}~255_{10}。两种符号表示法对于描述位模式来说都不是非常方便。二进制表示法太冗长,而十进制表示法与位模式的互相转化很麻烦。替代的方法是,以16为基数,或者叫做十六进制数,来表示位模式。十六进制使用数字‘0’~‘9’以及字符‘A’~‘F’来表示16个可能的值。下图展示了16个十六进制数字对应的十进制值和二进制值。

十六进制01234567
十进制01234567
二进制00000001001000110100010101100111
十六进制89ABCDEF
十进制89101112131415
二进制10001001101010111100110111101111

  在C语言中,以0x或0X开头的数字常量被认为是十六进制的值。字符‘A’~‘F’既可以是大写,也可以是小写,甚至是大小写混合。例如,我们可以将数字ED12AF16ED12AF_{16}写作0xED12AF,或者0xed12af,又或者是0xeD12Af。

十六进制与二进制转换

  编写机器级程序的一个常见任务就是在位模式的十进制、二进制和十六进制表示之间人工转换。还是上面那个十六进制数字0xED12AF,将它转换为二进制格式,如下所示:

      十六进制  E  D   1   2  A  F
      二进制  1110 1101 0001 0002 1010 1111

  这样就得到了二进制表示111011010001000210101111。

  反过来,如果给定一个二进制数字1101101101011111001001,可以把它分为每4位一组来转换十六进制。不过要注意,如果位总数不是4的倍数,最左边一组可以少于4位,前面用0补足。然后将每个4位组转换为相应的十六进制数字:

      二进制  0011  0110  1101  0111  1100  1001
      十六进制  3   6   D  7   C   9

十六进制与十进制转换

       十进制和十六进制表示之间的转换需要使用乘法或除法来处理一般情况。将一个十进制数字xx转换为十六进制,可以反复的用xx除以16,得到一个商qq和一个余数rr,也就是              x=q16+rx = q*16 + r。然后,我们用十六进制表示的rr作为最低位数字,并且通过对qq反复进行这个过程得到剩下的数字。例如,考虑十进制314456的转换:

              314456=1965316+8314456=19653*16+8    (8)

                19653=122816+519653=1228*16+5      (5)

                  1228=7616+121228=76*16+12        (C)

                     76=416+1276=4*16+12            (C)

                       4=016+44=0*16+4               (4)

   从这里,我们能读出十六进制表示为0x4CC58。

        反过来,将一个十六进制数转换为十进制数字,我可以用相应的16的幂乘以每个十六进制数字。比如,十六进制数0x53CD,我们计算它对应的十进制值为$516^3+316^2+12*16+13=21453$。