[英]Why does this code work to convert hexadecimal to decimal
此代码将一个十六进制数字转换为十进制数值。
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添加到数值中。
tolower(ch) - 'a'
的减法会将字符映射到字母a..f的0..5范围内的数字。 但是,十六进制数字a 16的(十进制)值是10 10 ,因此要将范围移回到需要的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,这不是根据最终“数字值”列所需的位置,该列显示每个十六进制数字的十进制数值。
表达式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()
函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.