为什么这段代码可以将十六进制转换为十进制

发布于 2024-10-19 02:34:49 字数 390 浏览 2 评论 0原文

此代码会将一个十六进制数字转换为十进制值。

int value;
// ch is a char variable holding a hexadecimal digit
if (isxdigit(ch))
    if (isdigit(ch))
        value = ch - '0';
    else
        value = tolower(ch) - 'a' + 10;
else
    fprintf(stderr, "%c is not a valid hex digit", ch);

我不完全理解它是如何工作的。我可以看到,根据 char 变量是数字还是字母,会减去不同的内容。我可以理解数字转换的部分,但我不明白为什么当字符是字母时必须将 10 添加到值中。

This code will convert one hexadecimal digit into a decimal value.

int value;
// ch is a char variable holding a hexadecimal digit
if (isxdigit(ch))
    if (isdigit(ch))
        value = ch - '0';
    else
        value = tolower(ch) - 'a' + 10;
else
    fprintf(stderr, "%c is not a valid hex digit", ch);

I don't fully understand how it works though. I can see that different things are subtracted from the char variable depending on whether it is a number or a letter. I can understand the part where a number gets converted, but I don't understand why 10 has to be added to the value when the character is a letter.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风铃鹿 2024-10-26 02:34:49

tolower(ch) - 'a' 的减法会将字母 a..f 的字符映射到 0..5 范围内的数字。但是,十六进制数字 a16 的(十进制)值为 1010,因此要将范围移回到需要的位置 10..15,10已添加。

也许这会有所帮助:

+---------+------------+-----------------+-------------+
Character | Subtracted | Resulting value | Digit value |
+---------+------------+-----------------+-------------+
|   '0'   |     '0'    |       0         |       0     |
|   '1'   |     '0'    |       1         |       1     |
|   '2'   |     '0'    |       2         |       2     |
|   '3'   |     '0'    |       3         |       3     |
|   '4'   |     '0'    |       4         |       4     |
|   '5'   |     '0'    |       5         |       5     |
|   '6'   |     '0'    |       6         |       6     |
|   '7'   |     '0'    |       7         |       7     |
|   '8'   |     '0'    |       8         |       8     |
|   '9'   |     '0'    |       9         |       9     |
|   'a'   |     'a'    |       0         |      10     |
|   'b'   |     'a'    |       1         |      11     |
|   'c'   |     'a'    |       2         |      12     |
|   'd'   |     'a'    |       3         |      13     |
|   'e'   |     'a'    |       4         |      14     |
|   'f'   |     'a'    |       5         |      15     |
+---------+------------+-----------------+-------------+

请注意“结果值”列如何在“a”处重置回 0,这不是根据最终“数字值”列所需的位置,该列以十进制显示每个十六进制数字的值。

The subtraction of tolower(ch) - 'a' will map the character to a number in the range 0..5 for the letters a..f. However, the (decimal) value of the hexadecimal digit a16 is 1010, so to move the range back up to 10..15 where it needs to be, 10 is added.

Perhaps this helps:

+---------+------------+-----------------+-------------+
Character | Subtracted | Resulting value | Digit value |
+---------+------------+-----------------+-------------+
|   '0'   |     '0'    |       0         |       0     |
|   '1'   |     '0'    |       1         |       1     |
|   '2'   |     '0'    |       2         |       2     |
|   '3'   |     '0'    |       3         |       3     |
|   '4'   |     '0'    |       4         |       4     |
|   '5'   |     '0'    |       5         |       5     |
|   '6'   |     '0'    |       6         |       6     |
|   '7'   |     '0'    |       7         |       7     |
|   '8'   |     '0'    |       8         |       8     |
|   '9'   |     '0'    |       9         |       9     |
|   'a'   |     'a'    |       0         |      10     |
|   'b'   |     'a'    |       1         |      11     |
|   'c'   |     'a'    |       2         |      12     |
|   'd'   |     'a'    |       3         |      13     |
|   'e'   |     'a'    |       4         |      14     |
|   'f'   |     'a'    |       5         |      15     |
+---------+------------+-----------------+-------------+

Notice how the "resulting value" column resets back to 0 at 'a', which is not where it needs to be according to the final "digit value" column, which shows each hexadecimal digit's value in decimal.

莫相离 2024-10-26 02:34:49

表达式 ch - '0' 之所以有效,是因为在 C 中“0 之后的每个字符的值应比前一个字符的值大 1”(C99 第 5.2.1 节)。

例如,字符 '3' 的值比 '0' 的值大 3,因此当您减去这两个值时,您将得到整数3.

表达式tolower(ch) - 'a' + 10 很幸运,因为除了上述数​​字约束之外,所有字符值都是实现定义的。

因此,当您减去 'c' - 'a' 时,您会得到 2(再加上 10,您会得到 12——该数字的正确值),因为大多数计算机都以 ASCII 或 EBCDIC 工作。但是当你在 DS9K 上运行这个程序时,你可能会得到 -42。

为了真正实现可移植,您需要依次将 ch 与六个字母中的每一个进行比较。这就是为什么有些系统提供 digittoint() 功能。

The expression ch - '0' works because in C "the value of each character after 0 ... shall be one greater than the value of the previous" (C99 section 5.2.1).

So, for example, the value of the character '3' is 3 greater than the value of '0', so when you subtract these two values, you get the integer 3.

The expression tolower(ch) - 'a' + 10 works by luck, because, except for the above constraint for digits, all values of characters are implementation-defined.

So when you subtract 'c' - 'a' you get 2 (and, adding 10, you get 12 – the correct value of that digit), because most computers work in ASCII or EBCDIC. But when you run this program on the DS9K, you might get −42.

To be truly portable you would need to compare ch to each of the six letters in turn. That's why some systems provide a digittoint() function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文