Вопрос-Ответ

Limiting floats to two decimal points

Ограничение значений с плавающей запятой двумя десятичными знаками

Я хочу, чтобы a было округлено до 13,95. Я пробовал использовать round, но получаю:

>>> a
13.949999999999999
>>> round(a, 2)
13.949999999999999

Аналогичную проблему со стандартным библиотечным классом Decimal см. в разделе Как я могу отформатировать десятичное число, чтобы оно всегда отображало 2 знака после запятой?.

Переведено автоматически
Ответ 1

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

При представлении с плавающей запятой ваша округленная версия будет тем же числом. Поскольку компьютеры являются двоичными, они хранят числа с плавающей запятой как целое число, а затем делят его на степень двойки, так что 13,95 будет представлено аналогично 125650429603636838 / (2 * * 53).

Числа двойной точности имеют точность 53 бита (16 цифр), а обычные числа с плавающей запятой имеют точность 24 бита (8 цифр). Тип с плавающей запятой в Python использует двойную точность для хранения значений.

Например,

>>> 125650429603636838/(2**53)
13.949999999999999

>>> 234042163/(2**24)
13.949999988079071

>>> a = 13.946
>>> print(a)
13.946
>>> print("%.2f" % a)
13.95
>>> round(a,2)
13.949999999999999
>>> print("%.2f" % round(a, 2))
13.95
>>> print("{:.2f}".format(a))
13.95
>>> print("{:.2f}".format(round(a, 2)))
13.95
>>> print("{:.15f}".format(round(a, 2)))
13.949999999999999

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


  1. Используйте целые числа и храните значения в центах, а не долларах, а затем разделите на 100, чтобы преобразовать в доллары.

  2. Или используйте число с фиксированной запятой, например decimal.

Ответ 2

Появились новые спецификации формата, Мини-язык спецификации формата строки:

Вы можете сделать то же самое, что и:

"{:.2f}".format(13.949999999999999)

Примечание 1: приведенное выше возвращает строку. Чтобы получить значение с плавающей запятой, просто оберните с помощью float(...):

float("{:.2f}".format(13.949999999999999))

Примечание 2: перенос с помощью float() ничего не меняет:

>>> x = 13.949999999999999999
>>> x
13.95
>>> g = float("{:.2f}".format(x))
>>> g
13.95
>>> x == g
True
>>> h = round(x, 2)
>>> h
13.95
>>> x == h
True
Ответ 3

Встроенный round() отлично работает в Python 2.7 или более поздней версии.

Пример:

>>> round(14.22222223, 2)
14.22

Ознакомьтесь с документацией.

Ответ 4

Позвольте мне привести пример в формате f-string / template-string в Python 3.6, который, на мой взгляд, очень аккуратный:

>>> f'{a:.2f}'

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

>>> print(f'Completed in {time.time() - start:.2f}s')
2023-07-04 01:23 python