Прошло больше месяца, новых знаний не писал. Итак, здесь я собираюсь написать об операторе по модулю в Python.
Наткнулся на оператор по модулю для отрицательных чисел. Я сталкивался с этим однажды. Итак, здесь я перечисляю, как работает модуль.
Краткое руководство по модулю:
Термин по модулю происходит из раздела математики, называемого модульной арифметикой. Оператор по модулю используется для получения значения в конечных границах. Классический пример — часы. Двенадцатичасовые часы имеют фиксированный набор значений от 1 до 12. Они имеют модуль 12.
Если мы хотим узнать, сколько времени будет через 7 часов после 8 утра, вы можете просто прибавить 7 к 8 и взять по модулю.
8 o'clock + 7 = 15 15 mod 12 = 3
Это означает, что 7 часов после 8:00 — это 15:00.
Теперь вы можете думать, что 15 и 3 эквивалентны в контексте мода 12. Модульная арифметика описывает это отношение как
a ≡ b(mod n)
Поместим это в наш пример:
15 ≡ 3 (mod 12)
читать как 15 конгруэнтно 3 по модулю 12.
Теперь давайте найдем модуль различных типов чисел.
Для положительного дивиденда и положительного делителя:
>>> 15%2 1
Для отрицательного делимого и положительного делителя:
>>> -15%2 1
Мы видим, что как для положительных, так и для отрицательных дивидендов положительный делитель дает нам положительный остаток.
Теперь перейдем к положительному делимому и отрицательному делителю:
>>> 15%-2 -1
Для отрицательного делимого и отрицательного делителя:
>>> -15%-2 -1
Мы видим, что для положительных и отрицательных дивидендов с отрицательным делителем мы получаем отрицательный остаток.
В Python есть метод divmod
, который дает нам и делимое, и остаток. Давайте посмотрим, какие значения мы получаем для вышеуказанных случаев:
>>> divmod(15,2) (7, 1) >>> divmod(-15,2) (-8, 1) >>> divmod(15,-2) (-8, -1) >>> divmod(-15,-2) (7, -1)
Мы видим, что для положительного делителя модуль положителен, а для отрицательного делителя остаток отрицателен. Дивиденд корректируется соответствующим образом.
Однако это правило не применяется в операторе по модулю чисел с плавающей запятой в зависимости от того, как вы получаете остаток:
>>> math.fmod(-12.0, 5.0) -2.0 >>> -12.0%5.0 3.0
Если мы получим остаток, используя math.fmod
, остаток будет отрицательным, даже если делитель положительный. В то время как, если мы поступим нормально по модулю, мы получим положительный остаток.
Почему это? Это из-за того, как язык получает частное — trucated division
или floor divison
.
Для усеченного деления, когда отрицательное частное округляется до нуля, используется следующее уравнение:
r = a — (n * trunc(a/n))
где
r = remainder a = dividend n = divisor
math.fmod
использует это правило truncated division
, поэтому мы получаем отрицательный остаток, когда делимое отрицательно, даже если делитель положительный.
Разработаем это уравнение:
r = -12.0 - (-5.0 * trunc(-12.0/5.0)) r = -12.0 - (-5.0 * trunc(-2.4)) r = -12.0 - (5.0 * -2) r = -12.0 + 10 r = -2
Для деления этажей, где отрицательное частное округляется от нуля, используется следующее уравнение:
r = a - (n * floor(a/n))
где
r = remainder a = dividend n = divisor
Простой модуль использует это floor division
, поэтому мы получаем положительный остаток, когда делимое отрицательно, а делитель положительный.
r = -12.0 - (5.0 * floor(-12.0/5.0)) r = -12.0 - (5.0 * floor(-2.4)) r = -12.0 - (5.0 * -3) r = -12.0 +15 r = 3
Вот и все.
В заключение, в Python для целых значений, если делитель положительный, остаток будет положительным, иначе отрицательным. Для отрицательных дивидендов с плавающей запятой это зависит от того, как вы получаете значение по модулю. Если вы используете обычный оператор %
, остаточное значение будет положительным из-за использования деления floor
. Если вы использовали math.fmod
, вы получите отрицательное значение остатка, так как будет использоваться truncated
деление.
Надеюсь, это было полезно. Спасибо за чтение. 🪁
Вдохновение:
Вы можете поддержать меня на Патреоне.