Упражнение по теме «Программирование на С: современный подход» - PullRequest
0 голосов
/ 18 января 2011

если бы кто-нибудь мог ответить мне, почему это работает, это было бы очень признательно. Упражнение (глава 4, примеры 7 и 8) говорит, что если у вас есть выражение: 9 - ((всего - 1)% 10) тогда у вас может возникнуть желание упростить это так: 10 - (всего% 10) Но это не сработает. Вместо этого он предлагает альтернативу: (10 - (всего% 10))% 10

Теперь я понимаю, как он попал на первое упрощение, но не то, почему оно не так или почему работает второе.

Заранее спасибо

Ответы [ 5 ]

4 голосов
/ 18 января 2011

x% m имеет диапазон (-m, m) в большинстве реализаций Си. Математически это обычно определяется из (0, m). Следовательно, добавив m, модуль снова преобразует C в математический.

3 голосов
/ 18 января 2011

Рассмотрим выходные данные для total = 10, чтобы увидеть, что второе выражение не эквивалентно.

Обратите также внимание, что третье выражение не эквивалентно первому выражению, если только total > 0 (поскольку поведение % определяется реализацией до C99 C и определяется, но не так, как вы хочу в С99).

Предполагая, что total > 0, первое и третье выражения эквивалентны из-за следующей математической идентичности:

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

Чтобы понять почему, представьте, что выполняете операции на циферблате.

1 голос
/ 18 января 2011

Это потому, что по модулю в C допускаются отрицательные числа.

так что -5% 10 это -5 вместо 5.

В первом случае значение 9 - ((всего - 1)% 10) всегда положительное.

Во втором случае он может быть отрицательным, если -10

Это обычная вещь для модуля, потому что, как правило, вы хотите, чтобы это было только для позитива (не уверен, почему они реализовали это для негативов).

0 голосов
/ 18 января 2011

Альтернатива не является упрощением, и ни одно из выражений не эквивалентно первому, поэтому предпосылка с самого начала имеет недостатки:

Следующее:

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

Последнее эквивалентно только целым числам больше нуля.

0 голосов
/ 18 января 2011

Чтобы показать, почему 9 - ((всего)% 10), используйте противоречие.

Пусть total = 10.

Тогда 9 - ((10-1)% 10) ==> 9- (9% 10) ==> 9-9 = 0.

Но 10- (10% 10) ==> 10 -0 = 10.

Таким образом, 10 - ((всего)% 10) не эквивалентно 9 - ((всего-1)% 10)

...