Какова цель результатов оператора отрицательного модуля? - PullRequest
2 голосов
/ 20 июля 2011

Ранее я был в (наивном) предположении, что оператор модуля вернул остаток от деления.Я был явно неправ, так как -2% 5 возвращает 3. Я бы подумал, что 5 делит -2 на ноль раз с -2 в качестве остатка.

Теперь я понимаю механизм выполнения этой операции, номой вопрос почему?Может ли кто-нибудь дать мне ссылку на что-то, объясняющее, почему модуль и остаток не являются синонимами, или пример ситуации, когда это было бы полезно?

Ответы [ 5 ]

3 голосов
/ 20 июля 2011

Результат совершенно верный.Модульная арифметика определяет следующее (я буду использовать «конгруэнтный», так как не могу набрать знак равенства с тремя строками)

a конгруэнтный b mod c, если ab кратен c, то есть x * c =(ab) для некоторого целого числа x.

Например,

0 congruent 0 mod 5 (0 * 5 = 0-0)
1 congruent 1 mod 5 (0 * 5 = 1-1)
2 congruent 2 mod 5 (0 * 5 = 2-2)
3 congruent 3 mod 5 (0 * 5 = 3-3)
4 congruent 4 mod 5 (0 * 5 = 4-4)
5 congruent 0 mod 5 (1 * 5 = 5-0)
6 congruent 1 mod 5 (1 * 5 = 6-1)
...

То же самое можно расширить до отрицательных целых чисел:

-1 congruent 4 mod 5 (-1 * 5 = -1-4)
-2 congruent 3 mod 5 (-1 * 5 = -2-3)
-3 congruent 2 mod 5 (-1 * 5 = -3-2)
-4 congruent 1 mod 5 (-1 * 5 = -4-1)
-5 congruent 5 mod 5 (-1 * 5 = -5-0)
-6 congruent 4 mod 5 (-2 * 5 = -6-4)
-7 congruent 3 mod 5 (-2 * 5 = -7-3)
...

Как видите, многоцелые числа являются конгруэнтными 3 mod 5: ..., -12, -7, -2, 3, 8, 13, ...

В математике набор этих чисел называется классом эквивалентности, индуцированнымотношение эквивалентности "конгруэнтность".Наше понимание остатка и определение функции «мод» основаны на этом классе эквивалентности.«Остаток» или результат вычисления мода является представительным элементом класса эквивалентности.По объявлению мы выбрали наименьший неотрицательный элемент (поэтому -2 не является допустимым кандидатом).

Поэтому, когда вы читаете -2 mod 5 = x, это переводится как «Найтинаименьший неотрицательный x, так что существует целое число y с y * 5 = -2 - x ", в соответствии с определением конгруэнтности.Решение - y = 1 и x = 3, как вы можете увидеть, просто опробовав другие значения для y.

2 голосов
/ 20 июля 2011

a = n (mod m) определяется как a = n + m*t и одинаково хорошо применяется к отрицательным числам. (Еще один взгляд на это: a = n (mod m) означает, что (a - n) кратно m)

-2 = 3 (мод 5), потому что -2 = 3 - 5 (т.е. t = -1)

Соглашение состоит в том, что результатом взятия modulo m является число от 0 до m - 1 (включительно)

1 голос
/ 20 июля 2011

Фундаментальная гарантия, которую вы получите, -

(a % b) + b * (a / b)  == a

Для значений со знаком нет причин, по которым знак должен быть предпочтительным результатом операции по модулю или делению. Некоторые языки исправляют одну форму, другие оставляют ее на усмотрение реализации, так что реализация может использовать любой способ, который обеспечивает оборудование. Аппаратная инструкция, в свою очередь, могла быть выбрана для эффективной работы аппаратного представления целых чисел со знаком.

Как правило, будьте очень осторожны при использовании целых чисел со знаком вместе с операциями деления, остатка и сдвига битов.

0 голосов
/ 20 июля 2011

Полагаю, это зависит от того, хотите ли вы, чтобы ваш результат был округлен в меньшую сторону или округлен до 0:

2 / 5 = 0.4 = 5*0 + 2 работает в обоих случаях, тогда как
-2 / 5 = -0.4 = 5*0 + -2, если вы округляете до 0 (усечение),
-2 / 5 = -0.4 = 5*-1 + 3, если вы округляете (пол).

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

hashmapBuckets[getIntHash(obj) % hashmapBuckets.size].add(obj)

или нормализации угла:

angle = angle % 360; //0-359

Фактически это другой случай I 'У меня возникли проблемы с поиском практических примеров для:)

-

О, и на странице Википедии, посвященной операции по модулю , есть несколько хороших графиков.Обратите внимание, что остаток всегда имеет тот же знак, что и делитель для этажного деления.

0 голосов
/ 20 июля 2011

Думайте о модуле как об операторе, который оборачивает линию длины y (в терминах y% x) вокруг круга из x колышков. В результате получается оставшаяся длина строки, которая не полностью переносится вокруг x.

...