简体   繁体   English

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

[英]Why does this code work to convert hexadecimal to decimal

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. 我可以看到从char变量中减去不同的东西,具体取决于它是数字还是字母。 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. 我可以理解数字转换的部分,但我不明白为什么当字符是字母时必须将10添加到数值中。

The subtraction of tolower(ch) - 'a' will map the character to a number in the range 0..5 for the letters a..f. tolower(ch) - 'a'的减法会将字符映射到字母a..f的0..5范围内的数字。 However, the (decimal) value of the hexadecimal digit a 16 is 10 10 , so to move the range back up to 10..15 where it needs to be, 10 is added. 但是,十六进制数字a 16的(十进制)值是10 10 ,因此要将范围移回到需要的10..15,添加10。

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. 注意“结果值”列如何在'a'处重置为0,这不是根据最终“数字值”列所需的位置,该列显示每个十六进制数字的十进制数值。

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). 表达式ch - '0'起作用,因为在C“中,0之后的每个字符的值应比前一个值大1”( C99第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. 因此,例如,字符'3'的值比'0'的值大3,因此当您减去这两个值时,您将得到整数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. 表达式tolower(ch) - 'a' + 10运气很好,因为除了上面的数字约束外,所有字符值都是实现定义的。

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. 因此,当你减去'c' - 'a'你得到2(并且,加上10,你得到12 - 该数字的正确值),因为大多数计算机都使用ASCII或EBCDIC。 But when you run this program on the DS9K, you might get −42. 但是当你在DS9K上运行这个程序时,你可能得到-42。

To be truly portable you would need to compare ch to each of the six letters in turn. 要真正便携,您需要依次将ch与六个字母中的每个字母进行比较。 That's why some systems provide a digittoint() function. 这就是为什么有些系统提供了digittoint()函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM