Language agnostic 为什么十六进制比十进制对机器更友好?
这可能是一个愚蠢的问题,因为我可以看到“16是2的幂”和“每个位代表2^(n个位)值”之间的关系,所以两个十六进制数字代表一个字节的可能值是合乎逻辑的。然而,我还是太盲目了,看不出它比十进制更好,因为无论哪种方法,它都需要转换成二进制Language agnostic 为什么十六进制比十进制对机器更友好?,language-agnostic,Language Agnostic,这可能是一个愚蠢的问题,因为我可以看到“16是2的幂”和“每个位代表2^(n个位)值”之间的关系,所以两个十六进制数字代表一个字节的可能值是合乎逻辑的。然而,我还是太盲目了,看不出它比十进制更好,因为无论哪种方法,它都需要转换成二进制 有人能解释一下低级伪编程中的数字符号转换过程,让它更容易理解吗?我真的看不出,如果转换仍在进行,转换过程会如何缩短。正如您所注意到的。两者都同样对机器友好。10和0x0a都是相同的数字。正如1/2和0.5在十进制中是相同的数字一样 从机器的角度来看,这无关紧要。机
有人能解释一下低级伪编程中的数字符号转换过程,让它更容易理解吗?我真的看不出,如果转换仍在进行,转换过程会如何缩短。正如您所注意到的。两者都同样对机器友好。
10
和0x0a
都是相同的数字。正如1/2和0.5在十进制中是相同的数字一样
从机器的角度来看,这无关紧要。机器看不到“10”或“0x0a”。机器只看到00001010
。事实上,甚至不是那样。机器中真正存在的是电压(或电荷)水平的两位,表示开启
,电压水平的八位,表示关闭
十六进制数字之所以流行,是因为它对“人类”来说更容易阅读。至少对于工程师和程序员来说(老实说,我有点犹豫是否要提到程序员,因为这对绝大多数程序员来说都不是真的)
首先,必须编写设备驱动程序的工程师和程序员很少关心变量的值是否为10、62、233或其他值。他们确实关心一个数字是否符合记忆。发送到硬件的值是用户的问题。不管天气好坏,发送的值是工程师或驾驶员必须处理的问题
对于这种情况,十六进制数字有一个非常显著的优势,因为每个字符正好与一个nybble对齐。这意味着一个字节正好由两个字符表示,两个字符正好代表一个字节。与此形成对比的是小数,其中一个字节需要三个字符,但三个字符最多可代表12位
快点,你能在一个字节里放133吗?也许您知道一个字节可以表示0-255之间的数字,所以这看起来很明显,但是像0x133这样的数字显然需要两个字节。事实上,为了更清楚地说明这一点,您经常会看到工程师在数据转储或文档中编写(hex)01 33
,以便更清楚地看到它是两个字节
它在更高的位计数下更有用。快点,你能把4311111放进32位吗?我有一个模糊的想法,32位大约是400万,但不确定这个数字是否适合32位。与它的十六进制表示法相比:0x100f655c7
更明显的是,至少需要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。因为第三位和第四位显然是c
(方波模式),所以添加位1,它变成d
您可能在想:等等,二进制表示不是更好吗。嗯,是的,(bin)0000 1101
显然是设置的第一、第三和第四位。二进制表示法的问题在于,任何高于8位的数字都会变得太大,以至于人眼很难理解,在实践中,与十六进制相比,它会导致更多的错误和误解
此外,没有多少语言支持二进制表示,大多数语言不允许在数字之间使用空格或其他分隔符(例如下划线),这使得数字比十六进制更不可读
十六进制并非总是工程师和(某些)程序员的首选表示形式。八进制数一度也同样流行。但是八进制和十进制有同样的问题。一个字节需要三个八进制数字来表示,但三个八进制数字实际上可以表示9位。所以它没有十六进制的完美除法
至少还有一种表示二进制值的方法非常流行。您已经看过很多次了,但可能还没有意识到它实际上是什么:IPv4地址的点十进制表示法实际上是一种编码,它将值表示为十进制值,但试图将它们放入内存结构中:
192.168.0.1 = 11000000 10101000 00000000 00000001
(192) (168) (0) (1)
唉,随着IPv6的发展,我们似乎已经决定回到十六进制编码。它不是对机器更友好,而是对人更友好。正如问题评论所指出的,机器几乎只处理比特。但他们以各种方式向人们展示设计元素。不同的机器设计在许多方面鼓励了两种编码的不同能力。现在标准的8位字节有明显的效果,但字节并不总是8位的。十六进制的大量使用来自于机器,特别是那些在接近通用微编码之前设计的机器,如何布置指令代码。在一些设计中,八进制更有意义。例如,Intel 8080 CPU有一条包含两个寄存器ID的
MOV
指令。以十六进制表示,各种寄存器组合产生的操作码范围从40
到7F
,没有明显的模式。但在八进制中,很明显:200
到277
,或者更确切地说是2xy
,其中x和y