2011-02-23 4 views
2

Ce code convertira un nombre hexadécimal en une valeur décimale.Pourquoi ce code fonctionne-t-il pour convertir un nombre hexadécimal en nombre décimal?

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); 

Je ne comprends pas très bien comment cela fonctionne. Je peux voir que différentes choses sont soustraites de la variable char selon qu'il s'agisse d'un nombre ou d'une lettre. Je peux comprendre la partie où un nombre est converti, mais je ne comprends pas pourquoi 10 doit être ajouté à la valeur quand le caractère est une lettre.

Répondre

11

La soustraction de tolower(ch) - 'a' mappera le caractère à un nombre compris entre 0..5 et les lettres a..f. Cependant, la valeur (décimale) du chiffre hexadécimal est 10 , donc pour déplacer la plage jusqu'à 10..15 où elle doit être, 10 est ajouté.

Peut-être cela aide:

+---------+------------+-----------------+-------------+ 
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  | 
+---------+------------+-----------------+-------------+ 

Remarquez comment la colonne « valeur résultante » remet à 0 à « a », ce qui est là où il doit être en fonction de la dernière colonne « valeur numérique », qui montre la valeur de chaque chiffre hexadécimal en décimal.

1

L'expression ch - '0' fonctionne car en C "la valeur de chaque caractère après 0 ... doit être supérieure à la valeur de la précédente" (C99 section 5.2.1).

Ainsi, par exemple, la valeur du caractère '3' est 3 supérieure à la valeur de '0', donc quand vous soustrayez ces deux valeurs, vous obtenez l'entier 3.

L'expression tolower(ch) - 'a' + 10 œuvres de chance, parce que , à l'exception de la contrainte ci-dessus pour les chiffres, toutes les valeurs de caractères sont définies par l'implémentation. Donc quand vous soustrayez 'c' - 'a' vous obtenez 2 (et, en ajoutant 10, vous obtenez 12 - la valeur correcte de ce chiffre), parce que la plupart des ordinateurs fonctionnent en ASCII ou EBCDIC. Mais lorsque vous exécutez ce programme sur le DS9K, vous pouvez obtenir -42. Pour être vraiment portable, vous devez comparer ch à chacune des six lettres l'une après l'autre. C'est pourquoi certains systèmes fournissent une fonction digittoint().

Questions connexes