开发者

Excercise in "C Programming: A modern Approach"

if anyone could answer me why this works, it would be greatly appreciated. The exercise (chapter 4, ex 7 and 8) says that if you have the expression: 9 - ((total - 1) % 10) then, you could be tempted to simplify it like this: 10 - (total % 10) But this wou开发者_运维知识库ld not work. Instead he offers the alternative: (10 - (total % 10)) % 10

Now, I understand how he got to the first simplification, but not why it's wrong, or why does the second one works.

Thanks in advance


x %m has a range of (-m, m) in most C implementations. Mathematically it is generally defined from (0, m). Hence by adding m the modulo again will convert the C to the mathematical one.


Consider the outputs for total = 10 to see that the second expression is not equivalent.

Note also that the third expression is not equivalent to the first expression unless total > 0 (because the behaviour of % is implementation-defined in pre-C99 C, and defined but not what you want in C99).

Assuming that total > 0, the first and third expressions are equivalent due to the following mathematical identity:

(a % b) == (((a + c) % b) - c) % b

To understand why, imagine doing the operations on a clock-face.


This is because modulo in C allows for negative numbers.

so -5 % 10 is -5 instead of 5.

In the first case, the 9 - ((total - 1) % 10) is always positive.

In the second case it can be negative if -10 < total < 0. In the 3rd case it is again wrapped around for negatives back into the positive range.

It is a common thing for modulo because generally you want it for positives only(not sure why they implemented it for negatives).


To show why 9-((total)%10) is wrong, use a contradiction.

Let total = 10.

Then 9-((10-1)%10) ==> 9-(9%10) ==> 9-9 = 0.

But, 10-(10%10) ==> 10 -0 = 10.

Thus, 10-((total)%10) is not equivalent to 9-((total-1)%10)


The alternative is not a simplification and neither expression is equvalent to the first so the premise is flawed from the start:

The following:

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 ) ;
}

Produces:

-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

The last is only equvalent for integers greater than zero.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜