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.
精彩评论