如果有人能回答我为什么会这样,那将非常感激。练习(第4章,前7和8)说如果你有这样的表达: 9 - ((总计 - 1)%10) 然后,你可能会像这样简化它: 10 - (总%10) 但这不起作用。相反,他提供了替代方案: (10 - (总%10))%10
现在,我理解他是如何进行第一次简化的,但不是为什么它是错的,或者为什么第二次有效。
提前致谢
答案 0 :(得分:4)
x%m具有(-m,m)的范围。数学上它通常由(0,m)定义。因此,通过添加m,模数将再次将C转换为数学模型。
答案 1 :(得分:3)
考虑total = 10
的输出,看第二个表达式是不等价的。
另请注意,第三个表达式 not 等同于第一个表达式,除非total > 0
(因为%
的行为是在C99 C之前的实现定义的,并且定义但不是你想要的C99)。
假设total > 0
,由于以下数学标识,第一个和第三个表达式是等价的:
(a % b) == (((a + c) % b) - c) % b
要理解原因,想象一下在钟面上进行操作。
答案 2 :(得分:1)
这是因为C中的模数允许负数。
所以-5%10是-5而不是5。
在第一种情况下,9 - ((总 - 1)%10)始终为正。
在第二种情况下,如果-10 <1,则它可以是负的。总计&lt; 0.在第三种情况下,它再次缠绕在负数回到正范围内。
模数是常见的,因为通常你只想要它为正数(不确定为什么它们为负数实现它)。
答案 3 :(得分:0)
要说明为什么9 - ((总)%10)错误,请使用矛盾。
让total
= 10。
然后9 - ((10-1)%10)==&gt; 9-(9%10)==&gt; 9-9 = 0。
但是,10-(10%10)==&gt; 10 -0 = 10.
因此,10 - ((总)%10)不等于9 - ((总计-1)%10)
答案 4 :(得分:0)
替代方案不是简化,并且两种表达都不等同于第一种,因此前提从一开始就存在缺陷:
以下内容:
int total ;
for( total = -10; total <= 10; total++ )
{
printf( "%d:\t%d\t%d\t%d\n", total,
9 - ((total - 1) % 10),
10 - (total % 10),
(10 - (total % 10)) % 10 ) ;
}
产地:
-10: 10 10 0
-9: 9 19 9
-8: 18 18 8
-7: 17 17 7
-6: 16 16 6
-5: 15 15 5
-4: 14 14 4
-3: 13 13 3
-2: 12 12 2
-1: 11 11 1
0: 10 10 0
1: 9 9 9
2: 8 8 8
3: 7 7 7
4: 6 6 6
5: 5 5 5
6: 4 4 4
7: 3 3 3
8: 2 2 2
9: 1 1 1
10: 0 10 0
对于大于零的整数,最后一个只是等价的。