Почему mod (%) является фундаментальным математическим оператором во многих языках программирования?

17

Существует ли какая-либо историческая или иная причина, почему оператор модуля является частью небольшого набора стандартных операторов в том, что выглядит как многие языки? ( +, -, *, /а %для Java и C - **в Ruby и Python).

Кажется странным включать мод как «фундаментальный» (чтобы не выбивать его, я его часто использую, но я также использую возведение в степень, абсолютное значение, пол / потолок или другие - они кажутся такими же полезными и необходимыми). Было ли это старое решение, принятое в какой-то спецификации, которой следуют все Java, C, Ruby и Python, или язык, от которого они произошли? Насколько я могу сказать, большинство диалектов Lisp включают только +, -, /и *.

Сначала я задавался вопросом, было ли мод особенно легко реализовать на бинарном уровне (будет ли это вообще иметь значение, принимая решение о том, что должно быть «фундаментальным» оператором, а что нет?), Но, похоже, это не так. Это просто гораздо чаще используется в программировании, чем я думаю?

Эли Роуз - ВОССТАНОВИТЬ МОНИКУ
источник

Ответы:

20

Я уверен, что это распространено, потому что многие архитектуры ЦП реализуют modulusв качестве второго вывода инструкции деления целых чисел.

Я не припоминаю, чтобы он присутствовал в процессорах 1970-х (6800, 8080, Z80, 1604 и т. Д.), Но к 1980-м у Intel 8086 и 8088, а также у Motorola 6809 были.

В архитектуре команд PDP-11 указывалось, что она DIVпроизводит частное и остаток с начала (1970 г.), хотя инструкции MUL и DIV не присутствовали в ранних проектах, но их можно было прозрачно эмулировать с помощью «ловушки, не реализованной командой», и реализовывать с обработчик, который сделал немного вертеться. Вероятно, функция PDP-11 поощряла самое первое издание языка C, предоставляющее эту %функцию. (Когда-нибудь замечали, как знак процента имеет косую черту? Это делает его умным выбором для оператора, связанного с делением.)

Наличие модуля в Cодиночку, вероятно, может объяснить его присутствие во всех современных языках. Cимеет очень большую семью потомков и был весьма влиятельным.

wallyk
источник
3
Влияние +1 C практически на все языки, не относящиеся к LISP, с начала 1970-х годов невозможно переоценить.
Росс Паттерсон
8

Многие языки программирования имеют оператор «остаток», который может использоваться как оператор модуля, когда оба операнда положительны; Указанный оператор часто называют оператором «модуль», потому что это его основное использование. В языках, как правило, есть такой оператор, потому что во многих аппаратных платформах аппаратное обеспечение автоматически предоставляет остаток при выполнении деления, и вычисление остатка или модуля с помощью любых других средств будет намного сложнее.

Я не знаю историю аппаратной поддержки для подписанного подразделения; многие процессоры на протяжении многих лет предоставляют аппаратное обеспечение, которое может автоматически выполнять подписанное деление в соответствии с правилом, согласно которому, если a / b даст (q, r), то -a / b или / -b приведут к (-q, -r), но Я не уверен в случаях использования, где деление с использованием этого правила особенно полезно. Почти в каждом случае, когда я использовал целочисленные операции деления или «модуля» для отрицательных значений, я хотел, чтобы округление в сторону отрицательной бесконечности деления и операция истинного модуля (чтобы (a + b) / b всегда равно (a / b) +1 и (a + b)% b всегда будет равно a% b.). Поскольку операторы не работают таким образом, необходимо проверить знак дивиденда и использовать другой код, когда он ' отрицательный - по сути, сводит на нет любую выгоду от наличия в первую очередь подписанной инструкции деления. Мне интересно, для каких целей поддержка аппаратного обеспечения с подписанным разделением действительно полезна.

Возвращаясь к исходному вопросу, оператор модуля часто полезен в ситуациях, когда определенные вещи должны происходить на периодической основе, либо в пространстве (например, в графических координатах), либо во времени. Например, если кто-то хочет, чтобы событие происходило каждые 15 секунд, время до следующего события будет 15 - ((time_now - time_of_an_occurrence)% 15), если предположитьtime_of_an_occurrencetime_now , что оно не больше, чем . Если значение time_of_an_occurrenceбольше чем time_now, оператор модуля мог бы продолжать использовать ту же формулу, если вычитание не переполняется, но для оператора остатка потребуется другая формула.

Supercat
источник
3
По этой причине в Haskell есть два оператора: remдля остатка и modдля модуля со свойствами, которые вы описываете.
Инго
@Complicatedseebio: Что особенно забавно, так это то, что его часто называют оператором модуля, потому что он обычно используется для вычисления модуля, даже когда для этого требуется подобный код m = number % base; if (m < 0) m+=base;. Я не знаю, видел ли я когда-нибудь код, который получал выгоду от отрицательного оператора оператора, за исключением, возможно q = n/d; if (n%d < 0) q+=1;, того, что в любом случае могло бы быть написано лучше другими способами.
суперкат
3

Модуль тесно связан с теорией групп и колец, которые являются очень фундаментальными математическими теориями.

Возведение в степень - это только третья операция в сложении, умножении, возведении в степень, тетратации (и это бесконечная последовательность). Это становится важным в основном с комплексными числами, которые являются более редкими в компьютерной арифметике. Одно конкретное возведение в степень поддерживается явно, хотя: 2 n обычно записывается как 1<<n, так как компьютеры довольно двоичные.

Пол и потолок действительно редки по сравнению: они применяются только при конвертации из ℝ в ℤ. (с плавающей точкой в ​​целое число). Точно так же absсвязано с отображением из ℤ в ℕ

MSalters
источник
ℤ - это целые числа (а ℕ - это подмножество целых чисел), вы должны иметь в виду от ℝ до ℤ.
Джони
@Joni: смешанные два примера, исправлено.
MSalters
0

Извините, но рискуя превратить это в игру "Call My Bluff", я думаю, что реальный ответ на этот вопрос довольно прост:

Мод позволяет выполнять точные вычисления в «недесятичных» количествах и единицах, таких как даты, время, ярды, дюймы, унции и т. Д. В десятичных вычислениях он также предоставляет программисту метод для работы с числовой точностью, превышающей ту, которую обеспечивает аппаратное обеспечение. машины. Это имеет огромное количество применений от очень маленьких (например, квантовые вычисления) до очень больших (например, обнаружение новых простых чисел).

Важно понимать, что мы назвали эти вещи компьютерами не без причины. Иногда нам нужно, чтобы они дали нам правильный ответ!


источник
Этот ответ не имеет смысла ... Какая связь между использованием "мода" и использованием различных модулей ???