Один из способов избежать вашей проблемы - использовать модуль decimal
, который работает в десятой базе и, таким образом, работает так, как работают люди (если бы мы были намного быстрее).
from decimal import Decimal
value = float(Decimal('32.31') * Decimal(1e9))
Это дает желаемое значение,
32310000000.0
Другой способ - использовать модуль fractions
, который работает с точными значениями:
from fractions import Fraction
value = float(Fraction('32.31') * Fraction(1e9))
Обратите внимание, что в обоих этих методах мы должны преобразовать 1e9
, а не только десятичное значение. Использование 1e9
в качестве числа с плавающей точкой преобразует промежуточные значения в число с плавающей точкой, и снова появляется проблема аппроксимации. В любом из этих способов вы могли бы прекратить окончательное преобразование в тип с плавающей запятой и просто продолжить работу со значением Decimal
или Fraction
. Любой из этих методов несколько медленнее, чем использование типов с плавающей точкой: вы получаете точность за счет скорости. Это снижение скорости может иметь значение в некоторых ситуациях.
Относительно вашего редактирования вашего вопроса: использование значения 1e-9
в любом из моих методов все равно приведет к тому, что вы хотите, а именно к значению 3.231e-08
.