





Ваш интерпретатор Python правильный. Один (глупый) способ вычисления модуля - вычесть или добавить модуль, пока результирующее значение не будет между 0 и (модуль - 1).
например.: 13 по модулю 5 = (13-5) по модулю 5 = (13-10) по модулю 5 = 3
или в вашем случае: −2 mod 5 = (−2 + 5) mod 5 = 3
Это зависит от того, как определяется целочисленное деление. Если при делении округляется до 0, то остаток должен иметь тот же знак, что и частное, так что b * (a/b) + a%b == a. Если деление округляется до отрицательной бесконечности (как в Python), остаток всегда должен быть положительным.
Ну, -2, разделенное на 5, даст 0 с остатком 3. Я не верю, что это должно сильно зависеть от платформы, но я видел более странные вещи.
Вы наверняка имеете в виду: «-2, разделенное на 5, будет -1, а остаток - 3», верно? Во всяком случае, это то, что делает Python.
В некоторых системах -2, деленное на 5, дает 0 с остатком -2. В других случаях это -1, а остаток - 3. Просто дело вкуса, "правильного" ответа не существует.
Это действительно 3. В модульная арифметика модуль - это просто остаток от деления, а остаток от -2, деленный на 5, равен 3.
В выражении c = a%bb означает модуль, а не c.
Результат операции модуля на негативе, по-видимому, зависит от языка программирования, и вот листинг http://en.wikipedia.org/wiki/Modulo_operation
Ну, 0% 5 должно быть 0, верно?
-1% 5 должно быть 4, потому что это следующая допустимая цифра, идущая в обратном направлении (то есть не может быть 5, так как это вне диапазона).
И, следуя этой логике, -2 должно быть 3.
Самый простой способ подумать о том, как это будет работать, - это продолжать добавлять или вычитать 5, пока число не окажется между 0 (включительно) и 5 (исключая).
Я не уверен в зависимости от машины - я никогда не видел такой реализации, но не могу сказать, что она никогда не была реализована.
Кстати: большинство языков программирования не согласятся с Python и выдадут результат -2. В зависимости от интерпретации модуля это верно. Однако наиболее согласованное математическое определение утверждает, что модуль а и б является (строго положительным) остатком р деления а / б. Точнее, 0 <= р <б по определению.
Результат зависит от языка. Python возвращает знак делителя, где, например, C# возвращает знак делимого (т.е. -2% 5 возвращает -2 в C#).
Одно из объяснений может заключаться в том, что отрицательные числа хранятся с использованием 2 дополнения. Когда интерпретатор python пытается выполнить операцию по модулю, он преобразуется в значение без знака. Таким образом, вместо выполнения (-2)% 5 он фактически вычисляет 0xFFFF_FFFF_FFFF_FFFD% 5, что равно 3.
Как объясняется в других ответах, есть много вариантов для операции по модулю с отрицательными значениями. Как правило, разные языки (и разные архитектуры машин) дают разный результат.
Согласно Справочное руководство по Python,
The modulo operator always yields a result with the same sign as its second operand (or zero); the absolute value of the result is strictly smaller than the absolute value of the second operand.
это выбор, сделанный Python. В основном по модулю определяется так, что это всегда выполняется:
x == (x/y)*y + (x%y)
поэтому имеет смысл, что (-2)% 5 = -2 - (-2/5) * 5 = 3
Будьте осторожны, чтобы не полагаться на это поведение мода в C / C++ во всех операционных системах и архитектурах. Если я правильно помню, я пытался полагаться на код C / C++, например
float x2 = x % n;
чтобы сохранить x2 в диапазоне от 0 до n-1, но когда я компилировал на одной ОС, вкрались отрицательные числа, но на другой ОС все будет работать нормально. Это было ужасно для отладки, так как это происходило только в половине случаев!
Как говорится в документации в Двоичные арифметические операции, Python гарантирует, что:
The integer division and modulo operators are connected by the following identity:
x == (x/y)*y + (x%y). Integer division and modulo are also connected with the built-in function divmod():divmod(x, y) == (x/y, x%y).
И действительно,
>>> divmod(-2, 5)
(-1, 3).
Другой способ визуализировать единообразие этого метода - вычислить divmod для небольшой последовательности чисел:
>>> for number in xrange(-10, 10):
... print divmod(number, 5)
...
(-2, 0)
(-2, 1)
(-2, 2)
(-2, 3)
(-2, 4)
(-1, 0)
(-1, 1)
(-1, 2)
(-1, 3)
(-1, 4)
(0, 0)
(0, 1)
(0, 2)
(0, 3)
(0, 4)
(1, 0)
(1, 1)
(1, 2)
(1, 3)
(1, 4)
Кажется, существует обычная путаница между терминами «по модулю» и «остаток».
В математике остаток должен быть определен всегда в соответствии с частным, так что если a / b == c rem d, то (c * b) + d == a. В зависимости от того, как округлить частное, вы получите разные остатки.
Однако по модулю всегда должен возвращаться результат 0 <= r < divisor, который согласуется с округлением до минус бесконечности, только если вы разрешаете отрицательные целые числа. Если деление округляется до нуля (что является обычным явлением), модуль и остаток эквивалентны только для неотрицательных значений.
Некоторые языки (особенно C и C++) не определяют требуемого поведения округления / остатка, а % неоднозначен. Многие определяют округление как направление к нулю, но используют термин по модулю, когда остаток был бы более правильным. Python относительно необычен тем, что округляет до отрицательной бесконечности, поэтому по модулю и остатку эквивалентны.
В Ada округляется к нулю IIRC, но есть операторы mod и rem.
Политика C предназначена для того, чтобы позволить компиляторам выбирать наиболее эффективную реализацию для машины, но IMO - это ложная оптимизация, по крайней мере, в наши дни. Хороший компилятор, вероятно, сможет использовать эквивалентность для оптимизации там, где отрицательное число не может появиться (и почти наверняка, если вы используете беззнаковые типы). С другой стороны, там, где могут встречаться отрицательные числа, вы почти наверняка заботитесь о деталях - по причинам переносимости вы должны использовать очень тщательно разработанные сверхкомплексные алгоритмы и / или проверки, чтобы гарантировать получение желаемых результатов независимо от округления и остатка. поведение.
Другими словами, выгода от этой «оптимизации» в основном (если не всегда) является иллюзией, тогда как в некоторых случаях есть очень реальные затраты - так что это ложная оптимизация.
Вы можете использовать
math.fmod, чтобы добиться того же поведения, что и в C или Java.