2014-10-08 5 views
1

Округление 1 десятичного не работает правильно:Python 2.7 раунд 1 десятичного не правильно

Смотрите ниже:

round(11.35, 1) 
11.3 

round(1.35, 1) 
1.4 

Как это может быть решена в Python?

Решение этой проблемы:

def round_decimal(value, rounding): 
    number = decimal.Decimal(str(value)) 
    decimal_point = float("1e%d" % -rounding) 
    return float(number.quantize(decimal.Decimal(str(decimal_point)))) 
+0

Да, у меня есть доступ в Интернет. Но я не нашел чистого способа решить эту проблему. – Robert

+0

Вы все еще застряли? –

+0

[documentation] (https://docs.python.org/2/library/functions.html#round) уже объясняет проблему и дает указатель для дальнейшего чтения. См. Примечание, которое начинается «Поведение round() для поплавков может быть неожиданным: ...». –

ответ

4

Это проблема с представлением десятичных чисел в компьютерах в целом (так неспецифической для Python).

Способ, которым я решил, что это решение, является использование стандартного библиотечного модуля decimal. В вашем случае это будет выглядеть примерно так:

num1 = decimal.Decimal("11.35") 
print num1.quantize(decimal.Decimal("0.1")) # round to one decimal 
# output: 11.4 

num2 = decimal.Decimal("1.35") 
print num2.quantize(decimal.Decimal("0.1")) 
# output: 1.4 
3

Причина этого заключается в том, что 11,35 проводится как float, который хранится с использованием двоичного представления чисел с плавающей точкой. И 11.35 нельзя представить точно как двоичное значение с плавающей запятой.

Представляемые двоичные значения с плавающей запятой имеют вид s × 2 e где s и e - целые числа. Обратите внимание, что 11.35 не может быть записано в этой форме. Что происходит в Python при написании 11.35, так это то, что система использует самое близкое представляемое значение.

closest double precision value to 11.35 является:

11.35 = + 11.34999 99999 99999 64472 86321 19949 90706 44378 66210 9375 

Это объясняет, почему round(11.35, 1) ведет себя, как это делает.

Интересно, что round(11.35, 1) даже не точно равно 11.3, поскольку 11.3 не является точно представимым с использованием двоичной с плавающей запятой. И так оно продолжается.

Если вы хотите точно указать 11.35, то вам нужно будет хранить его в десятичном типе данных. Стандартная библиотека decimal - это очевидный способ сделать это в Python. Этот вопрос подробно освещает эту тему: How can I format a decimal to always show 2 decimal places?

0

В дополнение к предыдущим ответам, я думаю, что полезно знать правила округления. Вы предполагаете, что значение 11.35 должно быть округлено до 11.4, но на самом деле округление - это вариант, когда вы нажимаете среднее значение в округлении. См.: http://en.wikipedia.org/wiki/Rounding

Использование десятичной библиотеки - лучший способ решить проблему в python для вашего случая.

Смежные вопросы