Что делает оператор по модулю (%) в Python?

Программирование и разработка

Начнем с перечисленной иллюстрации. Компания хочет использовать минимальное количество запросов к онлайн-сервису. Они также хотят завершить работу в параллельном режиме, чтобы минимизировать общее время, не тратя процессоры в состоянии простоя.

Когда они используют два параллельных запроса, они обнаруживают, что в последнем раунде занят только один процессор, а это означает, что другой простаивает. Они решают использовать три процессора и равномерно распределяют количество запросов… к своему удивлению, они снова все равно находят один процессор в последнем раунде, в то время как два других простаивают. В следующий раз они используют четыре процессора, затем пять, шесть… снова в результате чего в последнем раунде занят только один процессор, все остальные тратятся впустую. Наконец-то они используют семь процессоров, и все они работают одинаково, без потерь цикла.

Итак, что мы можем здесь узнать о наименьшем количестве запросов?

Введение

Возможно, вы слышали о проблеме распределения монет, которая очень похожа на ту, которая описана в аннотации. Давайте кратко рассмотрим его:

При раздаченнколичества монет среди двух, трех, четырех, пяти или шести человек, остается одна монета. Но если их распределить между семью людьми, то они распределятся поровну. Аналогично и в упомянутой выше задаче о параллельном процессоре число запросов полностью делится только на семь; один запрос остается в последнем раунде, когда их два, три, четыре, пять или шесть.

Следующие условные выражения могут правильно проверить значение n:

(
 (
  (% 2) == (% 3) == 
  (% 4) == (% 5) == 
  (% 6) == 1
 )
 and (% 7) == 0
)

Что %означает оператор по модулю? Это оператор модуля, который делит левую часть на правую и возвращает остаток ( а не частное). Нам нужно проверять натуральные числа, пока мы не достигнем значения, nпри котором вышеуказанное условие будет равно true. Мы можем сократить количество итераций за счет наименьшего общего кратного 2, 3, 4, 5и 6. Давайте придерживаться темы, а не примера.

Читайте также:  Как проверить, пуст ли массив в C?

Одним из наиболее распространенных примеров модуля является время на часах. Он продолжает округлять до наименьшего значения всякий раз, когда оно пересекает наибольшее значение. Например, после 59 минуты и секунды округляются до 0. Аналогично, значение часов становится 0 после 23 (для 24-часового формата) и 1 после 12 (для 12-часового формата). Чтобы реализовать ту же логику для минут и секунд в Python, мы можем сделать следующее:

var = var + 1
if (var == 60):   var = 0
var = var + 1
var = var % 60

Аналогичным образом мы можем реализовать логику часовой части в зависимости от типа часов (12-часовые или 24-часовые).

Модуль — ценная операция в информатике.

Практическое использование % для начинающих

Говоря с новыми программистами Python, можно сказать, что оператор модуля обычно используется следующим образом:

  1. Независимо от того, является ли число четным или нечетным: number % 2возвращает ненулевое значение ( True), если numberоно нечетное.
  2. Проверить, еслиНделится наМN % Mвозвращает значение 0, если Nоно делится на M.
  3. Проверить, еслиНкратноМN % Mвозвращает значение 0, если Nкратно M.
  4. Получите последнийМцифры числаН:N % (10 ** M)
  5. Значения переноса (для индексов массива): index = index % len(array)могут indexоставаться между 0и len(array) - 1, включительно.
  6. Принуждение числа к определенному кратному:tens = value - (value % 10)
  7. Ограничьте определенное значение: hour % 24возвращает число между 0и 23.
  8. Побитовые операции: x % 256то же значение, что и x & 255.
  9. Обычно используется в хешировании: h(k) = k % mсопоставляет ключ kс одним из mсегментов.

Программы, использующие оператор %

Следующие основные программы являются примерами других распространенных применений оператора модуля:

1. Возврат дроби вместо результата деления с десятичной точкой:

 # frac (7, 3) returns (2,1,3)
 # frac (6,  3) returns (2,0,3)
 # frac (6,0) returns (None,0,0)
 def frac(n, d):
     if d==0: return (None, 0, d)
     return (n//d, n%d, d)

2. Преобразование прошедшего времени (указанного в секундах) в часы, минуты и секунды:

 # time (5000) returns (1,23,20)
 # time (500) returns (0,8,20)
 # time (50) returns (0,0,50)
 def time(s):
     ss = s % 60
     s //= 60
     mm = s % 60
     s //= 60
     hh = s % 24
     return (hh, mm, ss)

3. О прогрессе сообщается только раз внтчаснт чвремя прохождения цикла (чтобы делать что-то каждыйнтчаснт читерация, а не выполнение на каждой итерации):

# loop (70) prints 0,10,20,30,40,50,60,69
 # loop (30) prints 0,10,29,29
 # loop (15) prints 0,10,14
 def loop(s):
     for i in range(s):
         if i%10 == 0:
             print(i,end=',')
     print(i)

4. Перестановка цифр в числе.

 # rev (1579) returns 9751
 # rev (234) returns 432
 # rev (60) returns 6
 def rev(n):
     r = 0
     while n>0:
         d = n % 10
         r = r * 10 + d
         n //= 10
     return r

5. Преобразование целого числа в десятичной системе счисления в другую систему счисления:

# octa (255) returns 377
 # octa (63) returns 77
 # octa (7) returns 7
 def octa(n):
     b = 8
     t = 1
     r = 0
     while n>0:
         d = n % b
         r = t * d + r
         t = t * 10
         n //= 8
     return r

6. Преобразование линейного массива в матричную структуру:

 # a1to2 ([10,20,30,40]) returns [[10, 20], [30, 40]]
 # a1to2 ([10,20,30,40,50]) returns [[10, 20], [30, 40], [50, 0]]
 # a1to2 ([10,20,30,40,50,60,70,80]) returns [[10, 20], [30, 40], [50, 60], [70, 80]]
 def a1to2(a1):
     s = len(a1)
     cols = int(s ** 0.5)
     rows = s // cols
     if rows*cols < s: rows = rows+1
     print(rows,cols)
     a2 = [[0 for i in range(cols)] for j in range(rows)]
     for i in range(s):
         r = i // cols
         c = i % cols
         a2[r][c] = a1[i]
     return a2

7. Вычисление наибольшего общего делителя:

 # gcd (12340,236) returns 4
 # gcd (10,20) returns 10
 # gcd (20,10) returns 10
 def gcd(a,b):
     if (a>b): x,y = a,
     else: x,y=b,a
     while y!=0:
         r = x % y
         x = y
         y = r
     return x

8. Вычисление наименьшего общего кратного:

 # lcm (20,30) returns 60
 # lcm (15,20) returns 60
 # lcm (30,7) returns 210
 def lcm(a,b):
     if (a>b): x,y = a,
     else: x,y=b,a
     l = y
     while l % x > 0:
         l = l + y
     return l

9. Проверка того, является ли число простым или составным:

 # is_prime (20) returns False
 # is_prime (19) returns True
 # is_prime (21) returns False
 def is_prime(n):
     if n<2: return False
     r = int(n**0.5)+1
     for i in range(2,r):
         if n % i == 0: return False
     return True;

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

Особенности оператора % в Python

Математически всегда гарантируется, что

если q, r = divmod(n, d),

тогда q * d + r == n.

Получает divmod()число nи делитель dв качестве параметров и возвращает частное qи остаток rв качестве результатов. Знак остатка зависит от знака делителя:

  • Положительный делитель дает положительный остаток.
  • Отрицательный делитель дает отрицательный остаток.

В следующей таблице показано сравнение положительных и отрицательных делителей в Python, а также обоснование.

Учитывать 21 % 4 равно 1 21% -4 это -3
Потому что 21 // 4 == 5 21 // -4 == -6
Сравнивать 5 * 4 + 1 == 21 ( -6 ) * (-4) + ( -3 ) == 21

Поведение %for intvs.Decimal

Так что же делает оператор «%» по модулю для объектов десятичного типа? В Python результат оператора %для Decimalобъектов типа отличается от результата оператора % для простых целых чисел.

Знак числителя используется с результатом, когда Decimalобъект используется в качестве операнда. В противном случае используется знак знаменателя.

# Four combinations of Signs of numerator vs. denominator
# for simple int values
#using `%` operator
print(«(21 % 4) is», 21 % 4) # 1
print(«(21 % -4) is», 21 % -4) # -3
print(«(-21 % 4) is», -21 % 4) # 3
print(«(-21 % -4) is», -21 % -4) # -1
print(«————————————————————«)
#using `divmod()` function
q, r = divmod(21, 4)
print(«divmod(21, 4) is», (q,r),»     ===>>   «,q,»*»,4,»+ «,r,»=»,21)
q, r = divmod(21, -4)
print(«divmod(21, -4) is», (q,r),»  ===>>  «,q,»*»,-4,»+»,r,»=»,21)
q, r = divmod(-21, 4)
print(«divmod(-21, 4) is», (q,r),»   ===>>  «,q,»*»,4,»+ «,r,»=»,-21)
q, r = divmod(-21, -4)
print(«divmod(-21, -4) is», (q,r),»  ===>>   «,q,»*»,-4,»+»,r,»=»,-21)

Знак остатка для простых целых чисел зависит от знаменателя.

В приведенном выше коде мы продемонстрировали изменение остатка из-за изменения знака знаменателя. В первой группе операторов используется %оператор, а в другой — divmod()функция для отображения частного для ясности значения остатка.

# Four combinations of Signs of numerator vs. denominator
# for Decimal type objects
from decimal import Decimal
for i in range(9):
    print(Decimal(i) % Decimal(4),» , «,
          Decimal(-i) % Decimal(4),» , «,
          Decimal(i) % Decimal(-4),» , «,
          Decimal(-i) % Decimal(-4))

Знак остатка для десятичных объектов зависит от числителя.

В приведенном выше коде результат содержит знак числителя, использованного в выражении. Значение остатка получается из простых (беззнаковых) значений операндов без соблюдения правила q * d + r == n.

Будьте осторожны при использовании Decimalобъектов с %оператором в Python. Результат отличается от результата простых целых чисел.

Подведение итогов и дальнейшие действия

Оператор модуля в Python представлен оператором %. Существуют и другие встроенные функции, подобные этой, divmod()которые можно использовать для вычисления остатка в результате деления. Для простых целых чисел Python q * d + r == nгарантирует q, r = divmod(n, d). Результат оператора %отличается, если операнды являются объектами типа Decimal.

Оцените статью
bestprogrammer.ru
Добавить комментарий