2011-02-23 63 views
2

此代碼將一個十六進制數字轉換爲十進制值。此代碼爲什麼要將十六進制轉換爲十進制

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。

回答

11

減去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,這是不需要它根據最後的「位值」欄是,它以十進制顯示每個十六進制數字的值。

1

表達式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()功能。

相關問題