为什么要使用十六进制
Why use hex?
嘿!我在查看此代码http://www.gnu.org/software/m68hc11/examples/primes_8c-source.html
我注意到,在某些情况下,他们使用十六进制数字,比如第134行:
for (j = 1; val && j <= 0x80; j <<= 1, q++)
现在他们为什么要使用0x80?我不太擅长十六进制,但我在网上找到了一个十六进制到十进制,它给了我128的0x80。
同样在第134行之前,在第114行,他们有这个:
small_n = (n & 0xffff0000) == 0;
从十六进制到十进制,我得到了4294901760的十六进制数。所以在这一行中,他们做了一个位AND,并将结果与0进行比较??
为什么不直接用这个号码呢?请任何人解释一下,并举例说明其他情况。
此外,我看到过只有十六进制数字的大行代码,但从未真正理解为什么:(
在您引用的两种情况下,数字的位模式都很重要,而不是实际数字。
例如,在第一种情况下,随着循环的进行,j
将是1,然后是2、4、8、16、32、64,最后是128。
在二进制中,即
0000:0001
、0000:0010
、0000:0100
、0000:1000
、0001:0000
、0010:0000
、0100:0000
和1000:0000
。
在C(直到C23)或C++(直到C++14)中没有二进制常数的选项,但在Hex中更清楚:0x01
、0x02
、0x04
、0x08
、0x10
、0x20
、0x40
和0x80
。
在第二个例子中,目标是删除值的下两个字节。因此,给定值1234567890,我们希望最终得到1234567168。
在十六进制中,它更清楚:以0x4996:02d2
开始,以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位值中,它是"1"answers"0"的16倍,而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...
有时,HEX中值的可视化表示会使代码更可读或更易于理解。例如,当观察数字的十进制表示时,位屏蔽或位的使用变得不明显。
这有时与特定值类型必须提供的空间量有关,因此也可能起到一定作用。
一个典型的例子可能是在二进制设置中,所以我们不使用十进制来显示一些值,而是使用二进制。
假设一个对象有一组非排他性的属性,这些属性的值为on或off(其中3个),表示这些属性状态的一种方法是使用3位。
有效的表示形式是十进制的0到7,但这并不明显。更明显的是二进制表示:
000,001,010,011,100,101,110,111
此外,有些人对hex非常满意。还需要注意的是,硬编码的幻数只是这些,无论使用的编号系统如何,都不那么重要
我希望这能有所帮助。
通常使用十六进制数而不是十进制数,这是因为计算机处理位(二进制数),当您处理位时,使用十六进制也更容易理解,因为从十六进制到二进制比从十进制到二进制更容易。
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来表示。
256基数会更简洁。每个可能的字节都可以有自己的单个字符,但大多数人类语言不使用256个字符,因此Hex是赢家。
为了理解简洁的重要性,可以考虑一下20世纪70年代,当你想检查你的兆字节内存时,它是用十六进制打印出来的。打印输出需要几千页的大纸。奥克塔尔会浪费更多的树木。
十六进制或十六进制,数字表示4位数据,0到15或以十六进制0到F表示。两个十六进制值表示一个字节。
更准确地说,十六进制和十进制都是数字。基数(基数10、16等)是以更清晰或更方便的方式表示这些数字的方法。
当讨论"有多少东西"时,我们通常使用十进制。当我们在计算机上查看地址或位模式时,通常首选十六进制,因为单个字节的含义通常很重要。
十六进制(和八进制)具有二次幂的性质,因此它们很好地映射了位的分组。十六进制将4位映射到一个十六进制半字节(0-F),因此一个字节存储在两个半字节(00-FF)中。八进制在数字设备(DEC)和其他旧机器上很流行,但一个八进制数字映射到三个比特,所以它不能很好地跨越字节边界。
总的来说,基数的选择是一种让编程更容易的方法——使用与域最匹配的基数。
看看这个文件,这是一些非常粗糙的代码。希望你擅长C,不要把它当作教程。。。
当你直接在位级别或略高于位级别时,十六进制很有用。例如,在驱动程序上工作时,你可以直接查看来自设备的位,并对结果进行处理,以便其他人可以读取连贯的结果。这是一个非常容易阅读的二进制表示。
- 为什么mpfr_printf与十六进制浮点(%a转换说明符)的printf不同
- 为什么C++总是显示十六进制内存地址,而不仅仅是整数?
- 为什么将字符串输出到未命名的 std::ofstream 反而给了我一个十六进制数?
- 为什么 std::hex 没有特别用字符打印为十六进制?
- 为什么将uint8_t读取为十六进制没有按预期工作?
- 为什么 .out 文件是十六进制而不是二进制
- C++为什么字符串的地址尽管是十六进制格式,但不能存储在 long int 变量中?
- 为什么在iOS枚举中使用十六进制而不是小数
- 为什么第二个语句是打印十六进制值
- 为什么打印字符串阵列输出十六进制
- 为什么十六进制地址是14个字符
- 为什么在C++17中使用十六进制浮点常量
- 为什么我在打印字符串时会得到十六进制值
- 为什么我的 RGB 转十六进制函数在传递颜色分量时返回 0
- 我的字节数组到十六进制字符串转换器有什么问题,或者为什么它在写入文件时会在某个位置后剪切符号?
- 为什么该函数以相反的顺序显示十六进制代码
- 为什么此输出看起来不确定?(是十六进制文字的冲刺、printf 还是语法?
- 为什么 int -> 十六进制/oct/bin 的转换在输出中打印为纯十进制值?
- 为什么我必须将一个字节强制转换为无符号两次才能看到十六进制输出
- 为什么这个程序的结果是三个十进制数"597, 295, 295,"输入两个十六进制数"255 127<enter>"