2008-09-11 6 views
93

В документации для функции round() указано, что вы передаете ей число, а позиции за десятичным знаком округлены. Таким образом, должны сделать это:round() в Python, похоже, не округляется должным образом

n = 5.59 
round(n, 1) # 5.6 

Но, в действительности, хорошие старые плавающей точкой странность закрадывается и вы получите:

5.5999999999999996 

Для целей UI, мне нужно, чтобы отобразить 5.6. Я ткнул по Интернету и нашел documentation, что это зависит от моей реализации Python. К сожалению, это происходит как на моей Windows-машине, так и на каждом Linux-сервере, который я пробовал. See here also.

Не удалось создать мою собственную круглую библиотеку, есть ли способ обойти это?

+2

Я попытался это с питоном 2.7.11 раундом (5.59), и это дает результат, 5.6 в обоих окнах и 64-разрядной машине linux x86, Cython? (Ссылка на упомянутую ссылку теперь изменена, я думаю) – 2016-04-11 04:16:25

+0

Где он на самом деле не работает правильно: `round (5.55, 1) = 5.5`. – Dmitry 2017-10-20 00:03:37

ответ

88

не может помочь так, как она хранится, но по крайней мере форматирования работает корректно:

'%.1f' % round(n, 1) # gives you '5.6' 
+5

Я попробовал `print '% .2f'% 655.665`, но он возвращает` 655.66`, это должно быть `655.67` – Kyrie 2015-07-15 03:56:07

+1

@Kyrie см. Http://stackoverflow.com/questions/9301690/python-float-round-error- 117-285 круглых к 117-28-не-117-29. В этом виновата погрешность с плавающей запятой - «5.665 -> 5.67», но «15.665 -> 15.66». Используйте десятичные знаки, если вам нужна точная точность. – Jimmy 2015-07-15 22:42:30

+5

Это работает после поиска :) `из десятичного импорта Decimal, ROUND_HALF_UP, ROUND_HALF_DOWN` # использование в округлении плавающих чисел ` Десятичный (str (655.665)). Quantize (Десятичный ('1.11'), округление = ROUND_HALF_UP) `# Проблемы и ограничения в плавающих точках – Kyrie 2015-07-16 01:22:04

-4

насчет:

round(n,1)+epsilon 
+0

Это будет работать только в том случае, если округление последовательно отходит от круглого числа эпсилон. Если `epsilon = .000001`, то` round (1.0/5.0, 1) + epsilon` примет точное представление 0.2 и сделает его 0.00001. Столь же плохие проблемы произойдут, если эпсилон окажется внутри круглой функции. – 2016-08-27 01:34:52

7

Вы можете переключить тип данных в целое число:

>>> n = 5.59 
>>> int(n * 10)/10.0 
5.5 
>>> int(n * 10 + 0.5) 
56 

И затем отобразите номер, вставив десятичный разделитель локали.

Однако, Jimmy's answer лучше.

+0

Это кажется самым надежным методом! – buzhidao 2017-09-28 10:10:43

3

Вы можете использовать оператор форматирования строк %, аналогичный sprintf.

mystring = "%.2f" % 5.5999 
11

Вы получаете '5.6', если вы str(round(n, 1)) вместо просто round(n, 1).

5

Математика с плавающей точкой уязвима для небольших, но раздражающих точных погрешностей. Если вы можете работать с целой или фиксированной точкой, вам гарантируется точность.

3

printf присоска.

print '%.1f' % 5.59 # returns 5.6 
92

Форматирование работает правильно даже без тура:

"%.1f" % n 
+11

В соответствии с [docs] (https://docs.python.org/3.2/tutorial/inputoutput.html#old-string-formatting) этот стиль форматирования строк в конечном итоге исчезнет. Формат нового стиля будет «{: .1f}». Format (n) ` – whereswalden 2014-08-07 12:56:32

18

round(5.59, 1) работает нормально. Проблема состоит в том, что 5.6 невозможно точно представить в двоичной плавающей запятой.

>>> 5.6 
5.5999999999999996 
>>> 

Как говорит Vinko, вы можете использовать форматирование строк для округления для отображения.

Python имеет module for decimal arithmetic, если вам это нужно.

4

Посмотрите на Decimal module

Decimal «основан на плавающей точкой модели, которая была разработана с людьми в виду, и обязательно имеет первостепенную руководящий принцип - компьютеры должны обеспечивать арифметика , которая работает так же, как арифметика , которую люди изучают в школе. "- выдержка из десятичной цифры арифметическая спецификация.

и

Десятичные числа могут быть представлены точно. Напротив, цифры, такие как 1.1 и 2.2, не имеют точных изображений в двоичном плавании . Конечным пользователям обычно не будет ожидать 1,1 + 2,2 для отображения как 3.3000000000000003, как и для двоичной с плавающей запятой.

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

19

Если вы используете десятичный модуль, вы можете ориентироваться без использования функции «круглый». Вот то, что я использую для округления, особенно при написании денежных приложений:

Decimal(str(16.2)).quantize(Decimal('.01'), rounding=ROUND_UP) 

Это возвращает десятичное число, которое 16,20.

2

Это действительно большая проблема. Попробуйте этот код:

print "%.2f" % (round((2*4.4+3*5.6+3*4.4)/8,2),) 

Отображается 4.85. Затем вы делаете:

print "Media = %.1f" % (round((2*4.4+3*5.6+3*4.4)/8,1),) 

и он показывает 4.8. Есть ли у Вас расчеты вручную точный ответ 4,85, но если вы попробуете:

print "Media = %.20f" % (round((2*4.4+3*5.6+3*4.4)/8,20),) 

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

2

Работы Совершенная

format(5.59, '.1f') # to display 
float(format(5.59, '.1f')) #to round 
1

Я делаю:

int(round(x , 0)) 

В этом случае мы первый раунд должным образом на уровне единицы, то преобразовать в целое, чтобы избежать печати поплавок.

так

>>> int(round(5.59,0)) 
6 

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

0

Здесь я вижу круглый провал. Что делать, если вы хотите округлить эти 2 числа до одного десятичного знака? 23,45 23,55 Мое образование было то, что от них округление вы должны получить: 23,4 23,6 «правило» в том, что вы должны округлить, если предыдущее число было нечетным, не сгонять, если предыдущее число было четным. Круглая функция питона просто обрежет 5.

0

Код:

x1 = 5.63 
x2 = 5.65 
print(float('%.2f' % round(x1,1))) # gives you '5.6' 
print(float('%.2f' % round(x2,1))) # gives you '5.7' 

Выход:

5.6 
5.7 

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

  • Нет связанных вопросов^_^