此代码为什么要将十六进制转换为十进制
问题描述:
此代码将一个十六进制数字转换为十进制值。此代码为什么要将十六进制转换为十进制
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(十进制)的值是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 |
+---------+------------+-----------------+-------------+
通知如何“所得的值”列复位回到0在a,这是不需要它根据最后的“位值”栏是,它以十进制显示每个十六进制数字的值。
答
表达式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()
功能。