C加法使用模数

C addition using modulus

我遇到了一个打印 A + B 的有趣 C 代码,但我很难理解它。

输入格式:

A B

其中 AB010 之间的整数,由单个 space.

分隔

代码:

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

这是为了简短的编码,请不要介意这些警告。

目前我的理解:

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

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

使用小端整数(并假设 ASCII 文本和 8 位字节,以及代码需要的所有其他假设),并忽略所有技术上的错误-modern-C代码中的东西,你的 "What I understand so far" 是正确的。

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

256 mod85是1,所以根据mod元运算的性质,

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

顺便说一下,对于 4 字节大端整数,我们得到

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

所以字节序并不重要,只要我们有 4 字节的整数。 (更大或更小的整数可能是个问题;例如,对于 8 字节整数,我们不得不担心 n 的字节中有什么 gets 没有设置。)

Space是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 的事实。