Ошибка Python в основном вычитании?

Возможный дубликат:
Ошибка округления Python с поплавковыми номерами
Ошибки в python

Я не могу заставить Python правильно выполнить вычитание 1 – 0,8 и назначить его. Он продолжает приходить с неправильным ответом, 0.19999999999999996.

Я немного изучил:

sq = {} sub = {} for i in range(1000): sq[str(i/1000.)+'**2']=((i/1000.)**2) sub['1-'+str(i/1000.)]=(1.0-(i/1000.)) 

и обнаружил, что эта ошибка происходит с несколько случайной группой поплавок от 0 до 1 до третьего десятичного знака. Аналогичная ошибка также возникает, когда вы группируете эти поплавки, но в другое подмножество.

Я надеюсь на объяснение этого и как заставить Python делать арифметическое право. Использование round(x,3) – это работа, которую я использую сейчас, но она не изящна.

Благодаря!

Это сеанс в моей оболочке Python 2.7.3:

 *** Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] on win32. *** *** Remote Python engine is active *** >>> 1-0.8 0.19999999999999996 >>> print 1-0.8 0.2 >>> a = 1-0.8 >>> a 0.19999999999999996 >>> print a 0.2 >>> a = 0.2 >>> print a 0.2 >>> a 0.2 >>> 

Вот код, который я вложил в пару онлайн-переводчиков:

 def doit(): d = {'a':1-0.8} return d print doit() 

и выход:

 {'a': 0.19999999999999996} 

    Плавающие числа не работают так, как вы ожидаете.

    Для начала прочитайте руководство по плавающей запятой . Короче говоря: компьютеры представляют числа с плавающей запятой как двоичные, и оказывается, что сохранение точной десятичной дроби как двоичного файла невозможно ( попробуйте сами на бумаге, чтобы понять, почему). Для практических целей 0.19999999999999996 «достаточно близко» к 0,2. Если вы хотите напечатать его как 0,2, вы можете сделать что-то вроде:

     print "%0.1f" % floating_point_value 

    Так что вы видите, это не ошибка. Это ожидаемое поведение.

    Используйте Decimal разработанный именно для этого:

     >>> from decimal import Decimal, getcontext >>> Decimal(1) - Decimal(0.8) Decimal('0.1999999999999999555910790150') >>> getcontext().prec = 3 >>> Decimal(1) - Decimal(0.8) Decimal('0.200') >>> float(Decimal(1) - Decimal(0.8)) 0.2 

    Python хранит float с «битами», а некоторые плавающие вы просто не можете точно представлять, независимо от того, сколько битов точности у вас есть. Это проблема, которую вы имеете здесь. Это похоже на попытку написать 1/3 в десятичной форме с ограниченным количеством десятичных знаков совершенно точно.