Подтвердить что ты не робот

Почему 1//0.1 == 9.0?

В Python 2.7 и 3.x, почему целочисленное деление дает мне неверное число при делении на число 0 < x < 1?

Отрицательные числа -1 < x < 0 работают корректно:

>>> 1//.1
9.0
>>> 1//-.1
-10.0

Я понимаю, что целочисленное деление с отрицательным (или положительным) числом округляется к отрицательной бесконечности, однако я бы подумал, что 1//.1 должен привести к 10.0, так как 1 можно разделить на .1 без остатка.

4b9b3361

Ответ 1

То, что вы видите здесь, по сути, является следствием разницы между "нормальным" делением с использованием / и деления пола с помощью //.

Также важно иметь в виду общую проблему с арифметикой с плавающей запятой, которая является определенной неточностью только из-за того, как они работают. В таких ситуациях всегда полезно использовать модуль decimal, чтобы проверить, что происходит на самом деле. Поэтому давайте посмотрим, что вы здесь делаете:

Прежде всего, .1 уже не является точным:

>>> Decimal(.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')

Итак, давайте посмотрим на фактический результат делений:

>>> Decimal(1) / Decimal(.1)
Decimal('9.999999999999999444888487687')
>>> 1 / .1
10.0

Как вы можете видеть, нормальное деление с использованием / точно не дает вам 10 с арифметикой с плавающей запятой. Но это действительно близко. Вот почему, когда вы используете обычные поплавки, вы действительно получаете обратно 10 (так как неточность деления сразу теряется при неточности номера номера).

При использовании разделки полов результат перекрывается до исправления неточности, поэтому вы получаете 9:

>>> Decimal(1) // Decimal(.1)
Decimal('9')
>>> 1 / .1
10.0

С отрицательными цифрами эффект напольного покрытия - это противоположное направление, как описано в этом другом вопросе:

>>> Decimal(1) / Decimal(-.1)
Decimal('-9.999999999999999444888487687')
>>> 1 / -.1
-10.0
>>> Decimal(1) // Decimal(-.1)
Decimal('-9')
>>> 1 // -.1
-10.0