【问题标题】:Why does this code work to convert hexadecimal to decimal为什么此代码可以将十六进制转换为十进制
【发布时间】:2011-07-02 15:51:23
【问题描述】:

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

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 添加到值中。

【问题讨论】:

    标签: c algorithm decimal hex


    【解决方案1】:

    tolower(ch) - 'a' 的减法会将字符映射到 0..5 范围内的数字(对于字母 a..f)。但是,十六进制数字 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,这不是根据最终“数字值”列需要的位置,该列以十进制显示每个十六进制数字的值。

    【讨论】:

      【解决方案2】:

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

      因此,例如,字符'3' 的值比'0' 的值大3,所以当你将这两个值相减时,你会得到整数3。

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

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

      要真正便携,您需要依次将ch 与六个字母中的每一个进行比较。这就是为什么有些系统提供digittoint() 函数的原因。

      【讨论】:

        猜你喜欢
        • 2019-01-01
        • 1970-01-01
        • 2011-07-28
        • 1970-01-01
        • 2014-01-15
        • 2018-09-04
        • 2017-07-31
        相关资源
        最近更新 更多