Почему оператор% называется оператором «модуля» вместо оператора «остатка»?
===========================================================================

Сегодня на работе у меня была интересная беседа с одним из моих коллег. Он был удивлен, когда с ним случилось следующее:

```
assert(-1 % 10 == -1)  //Expecting 9

```
Поэтому, когда он пришел спросить меня об этом, я сказал ему: «Ну, это имеет смысл. Когда вы делите -1 на 10, вы получаете 0 с оставшимся -1. Однако его аргумент состоял в том, что оператор модуля должен быть истинным для «всегда позитивная» модель. Я провел небольшое исследование и обнаружил, что модуль, на который он ссылался, выглядит следующим образом:

Пусть q целочисленное отношение a и n. Пусть г будет остаток. Затем:

a = n * q + r

ОпределениеI Однако использовалась версия модуля Кнута, которая:

Пусть q будет полом деленного на n. Пусть г будет остаток. Затем:

r = a - n * q

Итак, мой вопрос заключается в том, почему в стандарте FORTRAN (а впоследствии и в стандарте C) оказалось, что оператор модуля усекается до 0? Мне кажется неправильным называть это «модулем», а не «остатком» (в математике ответ действительно должен быть 9). Это связано с тем, как аппаратное обеспечение делает разделение?

Для справки:

[Википедия о модуле](https://en.wikipedia.org/wiki/Modulo_operation)[Запись MSDN об операторе "модуль"](https://msdn.microsoft.com/en-us/library/ty2ax9z9(v=vs.71).aspx)  
(Да, я понимаю, что это для VS2003 ... Я застрял с ним в настоящее время. Sadface)[Изменения оператора модуля](https://stackoverflow.com/q/3594964/550514)[Не принимайте положительный остаток ...](https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=6422581)**TLDR; Является ли аппаратное обеспечение причиной, по которой оператор модуля усекается до 0?**

 а не «остатком» (в математике ответ действительно должен быть 9).

C называет его оператором%, а его результат - остаток. C ++ копирует это из C. Ни один язык не называет это оператором модуля. Это также объясняет, почему остаток отрицательный: оператор / усекается до 0, а`(a / b) * b + (a % b)` должен равняться`a`.

редактироватьДэвид Родригес справедливо отмечает, что C ++делает определить класс шаблона`std::modulus`, который вызывает`operator%`, На мой взгляд, этот класс плохо назван. Копаясь немного, он унаследован от STL, где он уже назван, как сейчас. Загрузка для STL гласит: «STL был разработан на SGI MIPSproTM C ++ 7.0, 7.1, 7.2 и 7.2.1.» И, насколько я могу судить, фактически не имея компилятора и аппаратного обеспечения, MIPSpro передает деление на процессор и Аппаратные средства MIPS усекаются до 0, что означает`std::modulus` всегда был неправильно назван.



`%` является оператором остатка в C и C ++.

В стандарте C ++ это называется`%`оператор, и это даетостаток от деления, В стандарте C это называется`%` оператор и с C99 это фактически оператор остатка. Операторы по модулю и остатку различаются относительно отрицательных значений.

`%` оператор определен в C и C ++ с`a == (a / b * b) + a % b`.

Усечение целочисленного деления до 0 в C выполняется с C99. В C89 это было определено реализацией (и`%` может быть оператором по модулю в C89). C ++ также выполняет усечение до нуля для целочисленного деления.

Когда усечение сделано к нулю,`%` является оператором остатка, а знак результата является знаком дивиденда. Когда усечение сделано до минус бесконечности,`%` является оператором по модулю, а знак результата является знаком делителя.

По причинам, по которым C изменил поведение, определяемое реализацией целочисленного деления в отношении усечения, Дуг Гвин из комитета C сказал:

C99 наложил совместимое с Fortran требование в попытке привлечь больше программистов на Fortran и помочь конвертировать код Fortran в C.

Обоснование C99 говорит относительно усечения до деления с нулевым целым числом:

В Fortran, однако, результат всегда будет обрезаться до нуля, и накладные расходы, по-видимому, приемлемы для сообщества числового программирования. Следовательно, C99 теперь требует аналогичного поведения, что должно облегчить перенос кода с Fortran на C.

В`gcc` поведение реализации в C89 всегда было усечением до нуля.

Так`%` является оператором остатка в C99, C ++, а также в Java, но не является оператором остатка во всех языках программирования. В Ruby и Python,`%` фактически является оператором по модулю (целочисленное деление выполняется в направлении минус бесконечность в этих языках). Haskhell и Scheme имеют два отдельных оператора:`mod` а также`rem` для Хаскелла и`modulo` а также`remainder` для схемы.



 что проблема возникает из-за неправильного понимания математики. Конгруэнция по модулюотношение эквивалентноститак что это только определяетклассы эквивалентности, Следовательно, это**не** правильно сказать, чтов математике ответ действительно должен быть 9потому что это может быть и 19, 29, и так далее. И конечно это может быть -1 или -11. Существуют бесконечные элементы класса чисел n, которые являются n ≡ -1 mod (10).

[http://en.wikipedia.org/wiki/Modular\_arithmetic](https://en.wikipedia.org/wiki/Modular_arithmetic)

[http://en.wikipedia.org/wiki/Congruence\_relation](https://en.wikipedia.org/wiki/Congruence_relation)

Итак, правильный вопрос может быть таким: какой элемент класса чисел, которые являются ≡ -1 mod (10), будет результатом -1% 10 в C ++? И ответ:остаток деления -1 на 10. Никаких загадок.

PS Ваше определение модуля и Кнута эквивалентно ... :)