使用模数的 C 加法

我偶然发现了一个打印 A + B的有趣的 C 代码,但是我很难理解它。

输入格式:

A B

其中 AB010之间的整数,用一个空格隔开。

密码:

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

这是用于短代码,请不要介意的警告。

据我所知:

gets( &n )将 ASCII 值 A、 space 和 B 存储在 n的下三个字节中。例如,A = 3B = 8将产生 n = 0x00382033。给定条件防止 n溢出。但是我不明白 n % 85 - 43是如何产生 A + B的。

你是怎么得出这些数字的?

3307 次浏览

使用 little-endian int (假设使用 ASCII 文本和8位字节,以及代码所需的所有其他假设) ,忽略代码中所有技术上错误的现代 C 内容,您的“迄今为止我所理解的”是正确的。

gets(&n)将把 A、空间和 B 的 ASCII 值存储到 n的前3个字节中。它还将一个空终结符存储到第4个字节中。将这些 ASCII 值存储到 n的这些字节中将导致 n获取值 B*256*256 + space*256 + A,其中 BspaceA表示相应的 ASCII 值。

256 mod 85等于1根据同余关系的特性,

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

顺便说一下,对于4字节的 big-endian int,我们得到

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

所以 endianness 不重要,只要我们有4字节的 int。(大整数或小整数可能是个问题; 例如,对于8字节整数,我们必须考虑 n的字节中有哪些是 gets没有设置的。)

空格为 ASCII 32,数字字符的 ASCII 值为48 + 该数字的值。将 ab定义为输入的数字的数值(而不是数字字符的 ASCII 值) ,我们有

(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

其中最后两个等价依赖于 ab从0到9取值这一事实。