Me encontré con un código C intrigante que se imprime A + B, pero tengo problemas para entenderlo.
Formato de entrada:
A B
donde A, Bson números enteros entre 0y 10separados por un solo espacio.
Código:
main( n )
{
gets( &n );
printf("%d", n % 85 - 43);
}
Esto fue diseñado para codificación corta, no te preocupes por las advertencias.
Lo que entiendo hasta ahora:
gets( &n )almacena los valores ASCII de A, espacio y B en los tres bytes inferiores de n. Por ejemplo, A = 3y B = 8cedería n = 0x00382033. Las condiciones dadas evitan que se ndesborde. Pero no entiendo cómo n % 85 - 43cede A + B.
¿Cómo se les ocurren estos números?

01010101. Si prueba este enfoque con10101010, que es el número 170, obtiene una funcionalidad similar, la única diferencia es que si lo hace0 0, obtiene el número 128 (que está10000000en binario). Se utiliza una técnica similar para hacer un montón de optimizaciones con operaciones bit a bit, como contar el número de bits en un conjunto de bits utilizando máscaras como0x55555555y0xAAAAAAAA(0x55 = 85 y 0xAA = 170). Si busca en Google esos códigos hexadecimales, obtendrá un montón de artículos interesantes.Respuestas:
Con ints little-endian (y asumiendo texto ASCII y bytes de 8 bits, y todas las demás suposiciones que requiere el código), e ignorando todas las cosas técnicamente incorrectas en C moderno en el código, su "Lo que entiendo hasta ahora "es correcto.
gets(&n)almacenará los valores ASCII de A, espacio y B en los primeros 3 bytes den. También almacenará un terminador nulo en el cuarto byte. El almacenamiento de esos valores ASCII en esos bytes denresultados enntomando el valorB*256*256 + space*256 + A, dondeB,spaceyArepresentar los valores ASCII correspondientes.256 mod 85 es 1, por lo que según las propiedades de la aritmética modular,
(B*256*256 + space*256 + A) % 85 = (B + space + A) % 85Por cierto, con ints big-endian de 4 bytes, obtenemos
(A*256*256*256 + space*256*256 + B*256) % 85 = (B + space + A) % 85así que endianness no importa, siempre que tengamos entradas de 4 bytes. (Los ints más grandes o más pequeños podrían ser un problema; por ejemplo, con ints de 8 bytes, tendríamos que preocuparnos por lo que hay en los bytes
nquegetsno se configuraron).El espacio es ASCII 32 y el valor ASCII para un carácter de dígito es 48 + el valor del dígito. Definiendo
aybcomo los valores numéricos de los dígitos ingresados (en lugar de los valores ASCII de los caracteres de dígitos), tenemos(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 + bdonde las dos últimas equivalencias se basan en el hecho de que
aybtoman valores de 0 a 9.fuente