Странное поведение деления в питоне

Я пытаюсь решить эту проблему в хакерранк. В какой-то момент я должен проверить, делит ли число n(с учетом ввода) или нет.

Этот код работает отлично, за исключением одного теста (не проблема):

if __name__ == '__main__':
    tc = int(input().strip())
    for i_tc in range(tc):
        n = int(input().strip())
        while n % 2 == 0 and n is not 0:
            n >>= 1
        last = 0



        for i in range(3, int(n ** 0.5), 2):
            while n % i == 0 and n > 0:
                last = n
                n = n // i        # Concentrate here


        print(n if n > 2 else last)

Теперь вы можете видеть, что я делю число только тогда, когда i является фактором n. Например, если числа i = 2 и n = 4, то n / 2 и n // 2 не имеют никакого значения.

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

if __name__ == '__main__':
    tc = int(input().strip())
    for i_tc in range(tc):
        n = int(input().strip())
        while n % 2 == 0 and n is not 0:
            n >>= 1
        last = 0
        for i in range(3, int(n ** 0.5), 2):
            while n % i == 0 and n > 0:
                last = n
                n = n / i      # Notice this is not //
        print(n if n > 2 else last)

Это не первый раз. Даже для этой проблемы я сталкивался с одним и тем же. Для этой проблемы мне нужно делить только на 2, поэтому я использовал оператор сдвига вправо, чтобы избавиться от этого. Но здесь я ничего не могу сделать, так как право Сдвиг не может помочь мне.

Почему это происходит? Если числа маленькие, я не вижу никакой разницы, но когда число становится больше, оно как-то ведет себя по-другому.

Это даже не интуитивно, чтобы использовать // когда / не удается. Что является причиной этого?

1 ответ

Решение

Основная причина разницы между n // i а также n / i При условии n а также i имеют тип int а также n % i == 0 в том, что

  1. тип n // i все еще int тогда как тип n / i является float а также
  2. целые числа в Python имеют неограниченную точность, тогда как точность значений с плавающей точкой ограничена.

Следовательно, если значение n // i находится вне диапазона, который точно представлен питоном float тип, то он будет не равен вычисленному значению n / i,

Иллюстрация:

>>> (10**16-2)/2 == (10**16-2)//2
True
>>> (10**17-2)/2 == (10**17-2)//2
False
>>> int((10**17-2)//2)
49999999999999999
>>> int((10**17-2)/2)
50000000000000000
>>> 
Другие вопросы по тегам