Ich bin auf einen faszinierenden C-Code gestoßen A + B
, der gedruckt wird , aber ich habe Probleme, ihn zu verstehen.
Eingabeformat:
A B
wo A
, B
ganze Zahlen zwischen 0
und 10
durch ein Leerzeichen getrennt.
Code:
main( n )
{
gets( &n );
printf("%d", n % 85 - 43);
}
Dies war für die Kurzcodierung gedacht, bitte beachten Sie die Warnungen.
Was ich bisher verstehe:
gets( &n )
speichert die ASCII-Werte von A, Leerzeichen und B in den unteren drei Bytes von n
. Zum Beispiel A = 3
und B = 8
würde nachgeben n = 0x00382033
. Gegebene Bedingungen verhindern ein n
Überlaufen. Aber ich verstehe nicht, wie n % 85 - 43
Erträge A + B
.
Wie kommst du auf diese Zahlen?
01010101
. Wenn Sie diesen Ansatz mit10101010
der Nummer 170 versuchen , erhalten Sie eine ähnliche Funktionalität. Der einzige Unterschied besteht darin, dass Sie0 0
stattdessen die Nummer 128 erhalten (die10000000
binär ist). Eine ähnliche Technik wird verwendet, um eine Reihe von Optimierungen mit bitweisen Operationen durchzuführen, wie z. B. das Zählen der Anzahl von Bits in einem gesetzten Bit unter Verwendung von Masken wie0x55555555
und0xAAAAAAAA
(0x55 = 85 und 0xAA = 170). Wenn Sie diese hexadezimalen Codes googeln, erhalten Sie eine Reihe interessanter Artikel.Antworten:
Mit Little-Endian-Ints (und unter der Annahme von ASCII-Text und 8-Bit-Bytes und allen anderen Annahmen, die der Code erfordert) und dem Ignorieren aller technisch falschen modernen C-Inhalte im Code ist Ihr "Was ich verstehe soweit "ist richtig.
gets(&n)
speichert die ASCII-Werte von A, Leerzeichen und B in den ersten 3 Bytes vonn
. Es wird auch ein Null-Terminator im 4. Byte gespeichert. Speichern von ASCII jene Werte in diese Bytesn
Ergebnisse inn
den Wert nehmenB*256*256 + space*256 + A
, woB
,space
undA
stellen die entsprechenden ASCII - Werten.256 mod 85 ist 1, also durch die Eigenschaften der modularen Arithmetik,
(B*256*256 + space*256 + A) % 85 = (B + space + A) % 85
Übrigens bekommen wir mit 4-Byte-Big-Endian-Ints
(A*256*256*256 + space*256*256 + B*256) % 85 = (B + space + A) % 85
Endianness spielt also keine Rolle, solange wir 4-Byte-Ints haben. (Größere oder kleinere Ints könnten ein Problem sein. Bei 8-Byte-Ints müssten wir uns beispielsweise Gedanken darüber machen, was in den Bytes enthalten ist
n
,gets
die nicht festgelegt wurden.)Das Leerzeichen ist ASCII 32 und der ASCII-Wert für ein Ziffernzeichen ist 48 + der Wert der Ziffer. Definieren
a
undb
als numerische Werte der eingegebenen Ziffern (anstelle der ASCII-Werte der Ziffernzeichen) haben wir(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
wobei die letzten beiden Äquivalenzen auf der Tatsache beruhen, dass
a
undb
Werte von 0 bis 9 annehmen.quelle