练习“C编程:现代方法”

时间:2011-01-17 23:03:35

标签: c math modulo

如果有人能回答我为什么会这样,那将非常感激。练习(第4章,前7和8)说如果你有这样的表达: 9 - ((总计 - 1)%10) 然后,你可能会像这样简化它: 10 - (总%10) 但这不起作用。相反,他提供了替代方案: (10 - (总%10))%10

现在,我理解他是如何进行第一次简化的,但不是为什么它是错的,或者为什么第二次有效。

提前致谢

5 个答案:

答案 0 :(得分:4)

在大多数C实现中,

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

对于大于零的整数,最后一个只是等价的。