web-dev-qa-db-fra.com

Addition de C avec module

Je suis tombé sur un code C intrigant qui imprime A + B, Mais j'ai du mal à le comprendre.

Format d'entrée:

A B

A, B sont des entiers entre 0 et 10 séparés par un seul espace.

Code:

main( n )
{
    gets( &n );
    printf("%d", n % 85 - 43);
}

Ceci était destiné à un codage court, ne vous inquiétez pas des avertissements.

Ce que j'ai compris jusqu'ici:

gets( &n ) stocke les valeurs ASCII de A, espace et B dans les trois octets inférieurs de n. Par exemple, A = 3 et B = 8 Donnerait n = 0x00382033. Certaines conditions empêchent n de déborder, mais je ne comprends pas comment n % 85 - 43 Donne A + B.

Comment trouvez-vous ces chiffres?

80
William Lee

Avec des ints little-endian (et en supposant ASCII du texte, des octets de 8 bits et toutes les autres hypothèses requises par le code) et en ignorant tous les éléments techniquement erronés du code moderne , votre "Ce que je comprends jusqu'à présent" est correct.

gets(&n) stockera les ASCII valeurs de A, espace et B dans les 3 premiers octets de n. Il va également stocker un terminateur null dans le 4ème octet. Le stockage de ces valeurs ASCII dans les octets de n a pour résultat que n prend la valeur B*256*256 + space*256 + A, Où B, space et A représentent les valeurs ASCII correspondantes.

256 mod 85 est 1, donc par les propriétés de l'arithmétique modulaire,

(B*256*256 + space*256 + A) % 85 = (B + space + A) % 85

Incidemment, avec les ints big-endian de 4 octets, nous obtenons

(A*256*256*256 + space*256*256 + B*256) % 85 = (B + space + A) % 85

donc, l’endianisme n’a pas d’importance, tant que nous avons des ints de 4 octets. (Des entrées plus grandes ou plus petites pourraient être un problème; par exemple, avec les entrées de 8 octets, nous devrions nous préoccuper de ce que contiennent les octets de n que gets n'a pas définis.)

L'espace est ASCII 32, et la valeur ASCII d'un caractère numérique est égale à 48 + à la valeur du chiffre. Définissant a et b comme les valeurs numériques des chiffres entrés (plutôt que les valeurs ASCII des caractères numériques), nous avons

(B + space + A) % 85 = (b + 48 + 32 + a + 48) % 85
                     = (a + b + 128) % 85
                     = (a + b + 43) % 85

(B + space + A) % 85 - 43 = (a + b + 43) % 85 - 43
                          = (a + b) % 85
                          = a + b

où les deux dernières équivalences reposent sur le fait que a et b prennent des valeurs de 0 à 9.

87
user2357112