C-Addition unter Verwendung des Moduls

Lesezeit: 2 Minuten

Benutzeravatar von William Lee
William Lee

Ich bin auf einen faszinierenden C-Code gestoßen, der gedruckt werden kann A + Baber ich habe Schwierigkeiten, es zu verstehen.

Eingabeformat:

A B

wo A, B sind ganze Zahlen zwischen 0 und 10 durch ein einzelnes Leerzeichen getrennt.

Code:

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

Dies war für eine kurze Codierung gedacht, beachten Sie bitte die Warnungen.

Was ich bisher verstanden habe:

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 ergäbe n = 0x00382033. Gegebene Bedingungen verhindern n vom Überlaufen. Aber ich verstehe nicht wie n % 85 - 43 Erträge A + B.

Wie kommen Sie auf diese Zahlen?

  • In der Tat faszinierend.

    – Havenar

    19. Juli 2018 um 5:15 Uhr

  • Ein Hinweis ist, dass 85 binäre Bits sind, 01010101. Versucht man diesen Ansatz mit 10101010das ist die Nummer 170, erhalten Sie eine ähnliche Funktionalität, der einzige Unterschied besteht darin, wenn Sie mit tun 0 0 Sie erhalten stattdessen die Nummer 128 (was 10000000 binär). Eine ähnliche Technik wird verwendet, um eine Reihe von Optimierungen mit bitweisen Operationen durchzuführen, z. B. das Zählen der Anzahl von Bits in einem Bitsatz unter Verwendung von Masken wie z 0x55555555 und 0xAAAAAAAA (0x55 = 85 und 0xAA = 170). Wenn Sie diese Hexadezimalcodes googeln, erhalten Sie eine Reihe interessanter Artikel.

    – Havenar

    19. Juli 2018 um 5:33 Uhr


  • Wow, ich hätte nie so viel Tiefe in der Zahl 85 erwartet. Danke für den Einblick.

    – William Lee

    19. Juli 2018 um 6:35 Uhr

  • Ich nehme an, Sie meinen zwischen 0 und 9 einschließlich?

    – Rohr

    19. Juli 2018 um 16:52 Uhr

  • Das ist definitiv ioccc würdig.

    – dgnuff

    19. Juli 2018 um 20:02 Uhr

Benutzeravatar von user2357112
Benutzer2357112

Mit Little-Endian-Ints (und unter der Annahme von ASCII-Text und 8-Bit-Bytes und all den anderen Annahmen, die der Code erfordert) und dem Ignorieren all des technisch falschen in modernem C-Zeugs im Code, Ihr “Was ich verstehe bisher” ist richtig.

gets(&n) speichert die ASCII-Werte von A, Leerzeichen und B in den ersten 3 Bytes von n. Es speichert auch ein Null-Terminator im 4. Byte. Speichern dieser ASCII-Werte in diesen Bytes von n ergibt sich n Wert nehmen B*256*256 + space*256 + Awo B, spaceund A stellen die entsprechenden ASCII-Werte dar.

256 mod 85 ist 1, also durch die Eigenschaften der modularen Arithmetik,

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

Übrigens, mit 4-Byte-Big-Endian-Ints erhalten wir

(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 darstellen; bei 8-Byte-Ints müssten wir uns beispielsweise Gedanken darüber machen, was in den Bytes von enthalten ist n das gets nicht gesetzt.)

Das Leerzeichen ist ASCII 32, und der ASCII-Wert für ein Ziffernzeichen ist 48 + der Wert der Ziffer. Definieren a und b 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 darauf beruhen, dass a und b Werte von 0 bis 9 annehmen.

1418210cookie-checkC-Addition unter Verwendung des Moduls

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy