使用模量添加C

时间:2018-07-19 05:06:16

标签: c addition mod

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

输入格式:

A B

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

代码:

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

这是为简短编码而设计的,请不要在意警告。

到目前为止我所了解的:

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

您如何得出这些数字?

1 个答案:

答案 0 :(得分:87)

使用little-endian整数(并假设使用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

因此字节序无关紧要,只要我们有4字节的整数即可。 (较大或较小的整数可能是个问题;例如,对于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的事实。