Пол деления // vs int () округляется - PullRequest
0 голосов
/ 08 сентября 2018

Я новый пользователь Python 3.6.0. Я пытаюсь разделить 2 числа, которые дают большой результат. Однако, используя

return ans1 // ans2

производит 55347740058143507128 при использовании

return int(ans1 / ans2)

производит 55347740058143506432.

Что является более точным и почему это так?

Ответы [ 2 ]

0 голосов
/ 08 сентября 2018

Первый является более точным, поскольку дает точный целочисленный результат.

Второй представляет промежуточный результат в виде числа с плавающей точкой. Плавания имеют ограниченное разрешение ( 53 бита мантиссы ), в то время как для точного представления результата требуется 66 бит. Это приводит к потере точности.

Если мы посмотрим на шестнадцатеричное представление обоих результатов:

>>> hex(55347740058143507128)
'0x3001aac56864d42b8L'
>>> hex(55347740058143506432)
'0x3001aac56864d4000L'

мы видим, что младшие значащие биты результата, которые не помещались в 53-битную мантиссу, были установлены в ноль.

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

>>> int(float(55347740058143507128))
55347740058143506432L
0 голосов
/ 08 сентября 2018

Целочисленное деление настила в этом смысле более точное.

Проблема этой конструкции int(ans1 / ans2) заключается в том, что результатом является временно значение с плавающей запятой (перед тем, как, очевидно, преобразовать его в целое число), вводящее округление до ближайшего числа с плавающей запятой (величина округления зависит от величины числа ). Это даже можно увидеть, просто попытавшись обойти это значение через число с плавающей запятой:

print(int(float(55347740058143507128)))

Что печатает 55347740058143506432. Таким образом, поскольку обычный / приводит к плавающей точке, это ограничивает его точность.

...