Целочисленное деление Python дает неверный результат

Я не уверен, является ли это ошибкой или я просто неправильно понимаю, как должно работать целочисленное деление.

Рассмотрим следующий код:

import math
a = 18000
b = 5500
c = (a-b)/9  # c = 1388.(8)

d = (a-b)/c
e = (a-b)//c
f = math.floor(d)
print(f"(a-b)/c = {d}, (a-b)//c = {e}, floor = {f}")  # outputs (a-b)/c=9.0, (a-b)//c=8.0, floor=9

Почему e отличается от d? Насколько я понимаю, num1//num2 должно быть равно math.floor(num1/num2).

Использование 32-разрядной версии Python 3.8.10 в Windows 10 Pro.

Здесь работают нецелочисленные операции. У вас есть числа с плавающей запятой, например c. Проверьте, являются ли они точными.

gspr 16.02.2023 14:55
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
75
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Поскольку c — нецелое число типа float, целочисленное деление // может привести к неинтуитивным результатам. Лучше всего использовать // только при делении 2 целых чисел с целью создания int в качестве типа вывода.

Ответ принят как подходящий

Отличие здесь заключается в использовании промежуточных вычислений.

См. этот вопрос для получения более подробной информации о представлении с плавающей запятой.

(a-b)/9 не может быть точно представлено с плавающей запятой. В питоне он хранится как 1388.888888888888914152630604803562164306640625

from decimal import Decimal
print(Decimal(c))  # 1388.888888888888914152630604803562164306640625

Обратите внимание, что c на самом деле немного больше истинного значения (a-b)/9. Из-за этого истинное значение (a-b)/c немного меньше, чем 9. Floor-divide в python дает пол истинного значения деления, поэтому (a-b)//c правильно оценивается как 8.

С другой стороны, (a-b)/c приводит к другой ошибке точности с плавающей запятой. Хотя истинное значение немного меньше 9, ближайшее значение, которое может быть представлено, равно 9. Применение операции пола точно к 9 приводит к 9, как и ожидалось.

Другие вопросы по теме