English 中文(简体)
为什么要使用十六进制?
原标题:
  • 时间:2008-10-28 15:22:32
  •  标签:

嘿!我正在查看位于http://www.gnu.org/software/m68hc11/examples/primes_8c-source.html的代码。

我注意到在某些情况下他们使用了十六进制数,比如在第134行:

for (j = 1; val && j <= 0x80; j <<= 1, q++)

现在,他们为什么要使用0x80?我不是很擅长十六进制,但是我找到了一个在线十六进制转十进制的工具,它告诉我0x80相当于128。

还有,在第134行之前,在第114行他们有这个:

small_n = (n & 0xffff0000) == 0;

The hex to decimal gave me 4294901760 for that hex number. So here in this line they are making a bit AND and comparing the result to 0??

Why not just use the number? Can anyone please explain and please do give examples of other situations.

我也曾经看到一些仅由十六进制数字组成的大量代码,但从未真正理解其原因 :(

最佳回答

在你所引用的这两种情况中,数字的位模式是重要的,而不是实际的数字。

For example, In the first case, j is going to be 1, then 2, 4, 8, 16, 32, 64 and finally 128 as the loop progresses.

以二进制来表示,即

0000:00010000:00100000:01000000:10000001:00000010:00000100:00001000:0000

There s no option for binary constants in C (until C23) or C++ (until C++14), but it s a bit clearer in Hex: 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, and 0x80.

In the second example, the goal was to remove the lower two bytes of the value. So given a value of 1,234,567,890 we want to end up with 1,234,567,168.
In hex, it s clearer: start with 0x4996:02d2, end with 0x4996:0000.

问题回答

在十六进制(或八进制)数字和底层位模式之间存在直接映射,而在十进制中则不是这样。十进制数字9表示的与位模式有关的内容取决于它在哪一列以及哪些数字环绕它 - 它与位模式没有直接关系。在十六进制中,9始终表示1001,无论在哪一列。9 = 1001,95 = * 1001 * 0101等等。

作为我8位时代的遗物,我发现十六进制是二进制的便捷缩写。比特操作是一种正在消亡的技能。大约10年前,我在大学看到了一个第三年的网络论文,在课堂上只有10%(大约50人中的5人)的人能够计算比特掩码。

这是一个位掩码。十六进制值使得可以更容易地看到底层的二进制表示。n & 0xffff0000 返回n的前16位。0xffff0000 的意思是"二进制中前16位都为1,后16位都为0"。

0x80的意思是“1000000”,因此你从“00000001”开始,继续将该位向左移动“0000010”,“0000100”等,直到“1000000”。

0xffff0000 很容易理解,是一个 32 位值中 16 次“1”和 16 次“0”,而 4294901760 则是神奇的数字。

我发现令人疯狂的是,C编程语言系列一直支持八进制和十六进制,但没有直接支持二进制。我一直希望它们能够添加对二进制的直接支持。

int mask = 0b00001111;

许多年前/工作之前,当我在一个涉及大量的位级数学的项目上工作时,我感到厌烦了,并生成了一个包含所有可能的二进制值的定义常量的头文件,达到了8位:

#define b0        (0x00)
#define b1        (0x01)
#define b00       (0x00)
#define b01       (0x01)
#define b10       (0x02)
#define b11       (0x03)
#define b000      (0x00)
#define b001      (0x01)
...
#define b11111110 (0xFE)
#define b11111111 (0xFF)

它偶尔会使某些位级代码更加可读。

十六进制最大的用途可能是在嵌入式编程中。 十六进制数用于在硬件寄存器中屏蔽单个位,或将多个数值分割为一个8、16或32位寄存器中。

在指定单个位掩码时,很多人会先开始:

#define bit_0 1
#define bit_1 2
#define bit_2 4
#define bit_3 8
#define bit_4 16
etc...

过了一会儿,他们前进到:

#define bit_0 0x01
#define bit_1 0x02
#define bit_2 0x04
#define bit_3 0x08
#define bit_4 0x10
etc...

然后他们学会作弊,让编译器生成值作为编译时优化的一部分:

#define bit_0 (1<<0)
#define bit_1 (1<<1)
#define bit_2 (1<<2)
#define bit_3 (1<<3)
#define bit_4 (1<<4)
etc...

有时候,用十六进制的形式来表示数值可以使代码更易读或易懂。例如,在查看十进制数字表示时,位遮罩或位的使用变得不明显。

这有时可能与特定值类型提供的空间量有关,因此这也可能起到作用。

一个典型的例子可能在二进制环境中出现,因此我们使用二进制而不是十进制来表示某些值。

假设一个对象有一组非独占性属性,其值为开或关(共三个) - 表示这些属性的状态的一种方法是用3个比特来表示。

有效的表示方式是十进制的0到7,但这并不那么明显。更明显的是二进制表示方式:

000、001、010、011、100、101、110、111

此外,有些人对十六进制非常熟悉。请注意,硬编码的魔数只是这样而已,使用什么编号系统并不是非常重要。

希望可以帮到您。

通常使用十六进制数而不是十进制数是因为计算机使用比特(二进制数)工作,当你使用比特时,使用十六进制数更易理解,因为从十六进制转换为二进制比从十进制转换为二进制更容易。

OxFF = 1111 1111 ( F = 1111 )

但是

255 = 1111 1111 

因为

255 / 2 = 127 (rest 1)
127 / 2 = 63 (rest 1)
63 / 2 = 31 (rest 1)
... etc

您能看到吗?从十六进制到二进制更加简单。

一个字节有8个位。十六进制,也叫基础16,很简练。任意可能的字节值都可以用集合中的两个字符来表示,包括0到9以及a、b、c、d、e、f。

Base 256会更加简洁。每个可能的字节都可以有自己的单个字符,但大多数人类语言不使用256个字符,因此Hex是获胜者。

为了理解简明的重要性,考虑到回到 20 世纪 70 年代时,当你想检查自己的兆字节内存时,它会以十六进制形式打印出来。 打印机需要使用几千页大纸张来打印出来。 八进制就浪费更多的树了。

十六进制数字代表四个数据位,从0到15,或者在HEX中从0到F。两个十六进制值代表一个字节。

更确切地说,十六进制和十进制都是数字。基数(10、16等)是以更清晰或更方便的方式呈现这些数字的方法。

当讨论“有多少东西”时,我们通常使用十进制。当我们查看计算机上的地址或位模式时,通常优先使用十六进制,因为单个字节的含义可能很重要。

十六进制(以及八进制)具有二的次幂特性,因此它们可以很好地映射位的分组。十六进制将4位映射到一个十六进制数字(0-F),因此一个字节存储在两个十六进制数字(00-FF)中。八进制在Digital Equipment(DEC)和其他旧型机上很受欢迎,但一个八进制数字映射到三个位,因此它不能像十六进制那样很好地跨越字节边界。

总的来说,选择基数是一种使编程更容易的方法 - 使用最符合领域的基数。

看了一下这个文件,代码非常糟糕。希望你擅长C语言,而不是把它当作教程来学习。

十六进制在直接在比特级别或比特级别以上工作时非常有用。例如,在驱动程序上工作时,您正在直接查看来自设备的位并调整结果,以便其他人可以读取连贯的结果。它是二进制的一种紧凑而易于阅读的表示形式。





相关问题
热门标签