Dodawanie C za pomocą modułu


81

Natrafiłem na intrygujący kod C, który drukuje A + B, ale mam problem ze zrozumieniem.

Format wejściowy:

gdzie A, Bliczby całkowite od 0i 10oddzielone przez jedną przestrzeń.

Kod:

To było przeznaczone do krótkiego kodowania, proszę nie przejmować się ostrzeżeniami.

Co rozumiem do tej pory:

gets( &n )przechowuje wartości ASCII A, spacji i B w trzech niższych bajtach n. Na przykład A = 3i B = 8ustąpi n = 0x00382033. Podane warunki zapobiegają nprzepełnieniu. Ale nie rozumiem, jak n % 85 - 43plony A + B.

Jak wymyślasz te liczby?


2
Doprawdy intrygujące.
Havenard,

12
Podpowiedź jest to, że 85 bitów jest przemienne binarnie 01010101. Jeśli spróbujesz tego podejścia z 10101010liczbą 170, uzyskasz podobną funkcjonalność, jedyną różnicą jest to, że jeśli zrobisz z 0 0, zamiast tego otrzymasz liczbę 128 (która jest 10000000binarna). Podobna technika jest używana do wykonywania wielu optymalizacji z operacjami bitowymi, takimi jak zliczanie liczby bitów w zestawie bitów za pomocą masek, takich jak 0x55555555i 0xAAAAAAAA(0x55 = 85 i 0xAA = 170). Jeśli wygooglujesz te szesnastkowe kody, otrzymasz kilka interesujących artykułów.
Havenard,

Wow, nigdy nie spodziewałem się tak dużej głębokości w liczbie 85. Dzięki za wgląd.
William Lee,

1
Zakładam, że masz na myśli od 0 do 9 włącznie?
fajka

1
To zdecydowanie warte IOCCC .
dgnuff

Odpowiedzi:


87

Z little-endian ints (i zakładając tekst ASCII i 8-bitowe bajty oraz wszystkie inne założenia, których wymaga kod) i ignorując wszystkie technicznie błędne elementy w nowoczesnym C w kodzie, twoje „Co rozumiem jak dotąd ”jest poprawne.

gets(&n)zapisze wartości ASCII A, spacji i B w pierwszych 3 bajtach n. Przechowuje również terminator zerowy w czwartym bajcie. Przechowywanie tych wartości ASCII do tych bajtów npowoduje nprzyjmując wartość B*256*256 + space*256 + A, gdzie B, spacei Areprezentują odpowiednie wartości ASCII.

256 mod 85 to 1, a więc przez właściwości arytmetyki modularnej,

Nawiasem mówiąc, z 4-bajtowymi intami typu big-endian otrzymujemy

więc endianness nie ma znaczenia, o ile mamy 4-bajtowe liczby int. (Większe lub mniejsze wartości mogą stanowić problem; na przykład przy 8-bajtowych intach musielibyśmy się martwić o to, co jest w bajtach, nktóre getsnie zostały ustawione).

Spacja to ASCII 32, a wartość ASCII dla znaku cyfry to 48 + wartość cyfry. Definiując ai bjako wartości liczbowe wprowadzanych cyfr (zamiast wartości ASCII znaków cyfr), mamy

gdzie ostatnie dwa odpowiedniki polegają na tym, że ai bprzyjmują wartości od 0 do 9.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.