Странное поведение деления в питоне
Я пытаюсь решить эту проблему в хакерранк. В какой-то момент я должен проверить, делит ли число 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
в том, что
- тип
n // i
все ещеint
тогда как типn / i
являетсяfloat
а также - целые числа в 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
>>>