C加成使用模数

Wil*_*Lee 80 c addition mod

我遇到了一个有趣的C代码打印A + B,但我无法理解它.

输入格式:

A B
Run Code Online (Sandbox Code Playgroud)

其中A,B是一个整数之间0,10由一个空格分隔.

码:

main( n )
{
    gets( &n );
    printf("%d", n % 85 - 43);
}
Run Code Online (Sandbox Code Playgroud)

这是用于短编码,请不要介意警告.

到目前为止我所理解的:

gets( &n )将A,空格和B的ASCII值存储在较低的三个字节中n.例如,A = 3并且B = 8会屈服n = 0x00382033.鉴于条件防止n溢出.但我不明白n % 85 - 43收益率如何A + B.

你怎么想出这些数字?

use*_*ica 87

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

gets(&n)将A,空格和B的ASCII值存储到前3个字节中n.它还会在第4个字节中存储一个空终止符.存储这些ASCII值成那些字节n结果n取值B*256*256 + space*256 + A,其中B,spaceA表示对应的ASCII值.

256 mod 85是1,所以通过模运算的属性,

(B*256*256 + space*256 + A) % 85 = (B + space + A) % 85
Run Code Online (Sandbox Code Playgroud)

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

(A*256*256*256 + space*256*256 + B*256) % 85 = (B + space + A) % 85
Run Code Online (Sandbox Code Playgroud)

因此,只要我们有4字节的整数,字节顺序无关紧要.(更大或更小整数可能是一个问题;例如,具有8个字节的整数,我们就不用担心什么在的字节数ngets没有设置.)

空格为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
Run Code Online (Sandbox Code Playgroud)

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