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

Perl

print 2 % -18;

- >

-16

Tcl

puts [expr {2 % -18}]

- >

-16

но VBScript

wscript.echo 2 mod -18

- >

2

Почему разница?

Ответ 1

ответ на wikipedia здесь весьма полезен.

Краткий обзор состоит в том, что любое целое число можно определить как

a = qn + r

где все эти буквы являются целыми числами, а

0 <= | r | < | П |.

Для почти каждого языка программирования потребуется (a/n) * n + (a% n) = a. Поэтому определение модуля почти всегда будет зависеть от определения целочисленного деления. Существует два варианта для целочисленного деления на отрицательные числа 2/-18 = 0 или 2/-18 = -1. В зависимости от того, какой из них подходит для вашего языка, обычно изменяется оператор%.

Это связано с тем, что 2 = (-1) * -18 + (-16) и 2 = 0 * -18 + 2.

Для Perl ситуация сложная. На странице руководства говорится: "Обратите внимание, что когда use integer находится в области видимости," % "дает вам прямой доступ к оператору модуля, реализованному вашим C компилятор. Этот оператор не так хорошо определен для отрицательных операндов, но он будет выполняться быстрее". Таким образом, он может выбрать любой вариант для Perl (например, C), если использовать integer в области видимости. Если целое число используется не в объеме, в руководстве говорится: "Если значение $b отрицательно, то $a% $b равно $a минус наименьший кратный $b, который не меньше $a (т.е. результат будет меньше или равен равным нулю).

Ответ 2

Википедия "Modulo operation" страница объясняет это довольно хорошо. Я не буду пытаться делать здесь лучше, так как я, вероятно, сделаю тонкую, но важную ошибку.

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

Ответ 3

После деления числа и делителя, один из которых отрицателен, у вас есть как минимум два способа разделить их на частное и остаток, так что фактор-делитель + остаток = число: вы можете либо округлить частное отрицательной бесконечности или к нулю.

Многие языки просто выбирают один.

Я не могу устоять, указав, что Общий Lisp предлагает оба.

Ответ 4

python, конечно, явно сообщает вам

>>> divmod(2,-18)
(-1, -16)