为什么十六进制比十进制更加机器友好?

时间:2013-11-29 02:13:43

标签: language-agnostic

这可能是一个愚蠢的问题,因为我可以看到“16是2的幂”和“每个位代表2 ^(n个位)值”之间的关系,所以两个十六进制数字代表一个逻辑是合乎逻辑的字节的可能值。但是我仍然太盲目,看不出它会比十进制更好,因为它需要转换成二进制。

有人能解释低级伪编程中的数字符号转换过程,使其更容易理解吗?如果 正在进行转换,我真的看不到转换过程如何缩短。

2 个答案:

答案 0 :(得分:7)

正如你所注意到的那样。两者都是机器友好的。 100x0a都是相同的数字。同样,1/2和0.5是十进制相同的数字。

从机器的角度来看并不重要。机器看不到“10”或“0x0a”。机器只看到00001010。实际上,甚至没有。机器中真正的两个位是电压(或电荷)电平的两位,代表on,八位代表off的电压电平。

十六进制数字普及的原因是它更容易阅读“人类”。至少对工程师和程序员来说(说实话,我有点犹豫不决提到程序员,因为绝大多数程序员都不这么认为。)

首先,必须编写设备驱动程序的工程师和程序员很少关心变量的值是10还是62或233或其他什么。如果数字符合内存,他们会关心。发送到硬件的值是用户的问题。是否可以发送价值的天气是工程师或司机作家必须处理的。

对于这个十六进制数字具有非常显着的优势,因为每个字符恰好对齐一个nybble。这意味着一个字节由两个字符表示,两个字符恰好代表一个字节。将此与小数形成对比,其中一个字节需要三个字符,但三个字符最多可以代表12位。

很快,你能在一个字节内安装133吗?也许你知道一个字节可以表示0-255之间的数字,所以看起来很明显,但像0x133这样的数字显然需要两个字节。实际上,为了使其更清晰,您经常会看到工程师在数据转储或文档中编写(hex) 01 33,以使其更明显是两个字节。

它在更高的位数时更有用。快,你能用32位装4311111111吗?我有一个模糊的想法,32位大约是400万,但不确定这个数字是否适合32位。将其与十六进制表示形成对比:0x1 00F6 55C7更明显的是,您需要至少33位来表示该数字。

工程师也习惯于以十六进制的方式查看位模式。基本模式很简单:

1 = first bit
2 = second bit
4 = third bit
8 = fourth bit

所以,如果你想在寄存器中设置第19位,你的思考过程会是这样的:

Bit 19 is after the 16th bit. And you know that the 16th bit is `0x0000 8000`
(when I think in hex, my mind always add the blank spaces for clarity).
19 is 3 bits higher than 16. And the number that represents the third bit is 4.
So bit number 19 is: `0x0004 0000`

我提到的关于第16位的部分是大多数工程师训练读取十六进制识别的另一种基本模式:

00 00 00 80 = bit no 8
00 00 80 00 = bit no 16
00 80 00 00 = bit no 24
80 00 00 00 = bit no 32

我训练自己认识的另一种常见模式是方波:

         _   _   _   _
0x55 = _| |_| |_| |_|   (01010101)
       _   _   _   _
0xaa =  |_| |_| |_| |_  (10101010)
           _ _     _ _
0x33 = _ _|   |_ _|     (00110011)
       _ _     _ _
0xcc =    |_ _|   |_ _  (11001100)
         _ _     _ _
0x66 = _|   |_ _|   |_  (01100110)
       _     _ _     _
0x99 =  |_ _|   |_ _|   (10011001)
       _ _ _ _ 
0xf0 =        |_ _ _ _  (11110000)
               _ _ _ _ 
0x0f = _ _ _ _|         (00001111)

这意味着,对于像我这样的人,如果你告诉我你想在2秒内设置一个变量的第一,第三和第四位,我会去Aha:0x0d。因为显然第三和第f位是c(方波图案),所以添加第一位,它变为d

你可能在想自己:等一下,二进制表示不会更好。嗯,是(bin) 0000 1101更明显是第一,第三和第四位设置。二进制表示的问题在于,在任何高于8位的情况下,数字变得太大而人眼无法容易理解,并且在实践中与十六进制相比会导致更多的错误和误解。

此外,没有多少语言支持二进制表示,而且大多数语言都不允许在数字之间使用空格或其他分隔符(例如下划线),这使得数字与十六进制相比更难以阅读。

十六进制并不总是工程师和(某些)程序员的首选代表。在某一点上,八进制数字同样受欢迎。但八进制与十进制有相同的问题。一个字节需要三个八进制数字来表示,但三个八进制数字实际上可以代表9位。因此它没有十六进制所具有的那种完美的分裂。

至少有一种其他方法可以表示非常受欢迎的二进制值。你已经多次看过了,但可能还没有意识到它实际上是什么:IPv4地址的点分十进制表示法实际上是一个编码,它将值表示为十进制但是试图使它们适合内存结构:

192.168.0.1 = 11000000 10101000 00000000 00000001
               (192)     (168)     (0)     (1)

唉,随着我们推进IPv6,我们似乎决定回到十六进制编码。

答案 1 :(得分:3)

它不是更适合机器使用,它更适合人们使用。正如问题评论指出的那样,机器几乎只处理比特。但它们以各种方式向人们展示设计元素。不同的机器设计以多种方式鼓励不同的两种幂编码。现在标准的8位字节有明显的效果,但字节并不总是8位。很多十六进制的使用来自机器,特别是那些在近通用微码之前设计的机器,它们是如何布置指令代码的。在某些设计中,八进制更有意义。例如,Intel 8080 CPU的MOV指令包含两个寄存器ID。以十六进制表示,各种寄存器组合产生的操作码范围从407F,没有明显的模式。但是在八进制中,很明显:200277,或者更确切地说2xy,其中 x y 是寄存器。