C додавання за допомогою модуля


81

Я натрапив на інтригуючий код С, який друкується A + B, але у мене проблеми з його розумінням.

Вхідний формат:

де A, B- цілі числа між 0і 10розділені єдиним пробілом.

Код:

Це було призначено для короткого кодування, будь ласка, не забувайте про попередження.

Що я досі розумію:

gets( &n )зберігає значення ASCII A, пробілу та B у нижчих трьох байтах n. Наприклад, A = 3і B = 8дало б n = 0x00382033. Дані умови запобігають nпереповненню. Але я не розумію, як n % 85 - 43урожай A + B.

Як ви придумуєте ці цифри?


2
Справді інтригуюче.
Havenard

12
Підказка в тому , що 85 чергуються бітів в довічним вигляді , 01010101. Якщо ви спробуєте цей підхід із 10101010, тобто номером 170, ви отримаєте подібну функціональність, єдина різниця полягає в тому, що якщо ви зробите з цим, 0 0ви отримаєте замість цього число 128 (яке є 10000000в двійковому вигляді). Подібний прийом використовується для здійснення купу оптимізацій з побітовими операціями, такими як підрахунок кількості бітів у наборі бітів за допомогою масок, таких як 0x55555555і 0xAAAAAAAA(0x55 = 85 та 0xAA = 170). Якщо погуглити ці шістнадцяткові коди, ви отримаєте купу цікавих статей.
Havenard

Ого, я ніколи не очікував такої глибини в номері 85. Дякую за розуміння.
Вільям Лі,

1
Припускаю, ви маєте на увазі від 0 до 9 включно?
труба

1
Це однозначно ioccc гідно.
dgnuff

Відповіді:


87

З мало-ендіанськими ints (і припускаючи текст ASCII, і 8-бітові байти, і всі інші припущення, які вимагає код), і ігноруючи всі технічно помилкові в сучасному-C речі в коді, ваш "Що я розумію поки що "правильно.

gets(&n)буде зберігати значення ASCII A, пробілу та B у перші 3 байти n. Він також збереже нульовий термінатор у 4-му байті. Збереження цих ASCII значення в ці байти nрезультатів в nприймаючому значення B*256*256 + space*256 + A, де B, spaceі Aпредставляють відповідні значення ASCII.

256 мод 85 дорівнює 1, тому за властивостями модульної арифметики,

До речі, ми отримуємо 4-байтові великі ендіанські інти

тому ендіанність не має значення, якщо у нас є 4-байтові вставки. (Більші чи менші ints можуть бути проблемою; наприклад, з 8-байтовими ints нам доведеться турбуватися про те, що в байтах nцього getsне встановлено.)

Пробіл - ASCII 32, а значення ASCII для символу цифри - 48 + значення цифри. Визначаючи aі bяк числові значення введених цифр (а не значення ASCII символів цифр), ми маємо

де дві останні еквівалентності покладаються на той факт, що aі bприймають значення від 0 до 9.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.