Как округлить число с плавающей запятой до определенного десятичного знака?
Предположим, у меня возникли 8.8333333333333339
и я хочу преобразовать его в 8.84
, Как я могу сделать это в Python? round(8.8333333333333339, 2)
дает 8.83
, а не 8.84
. Я новичок в Python и программирования в целом.
Я не хочу печатать его в виде строки, результат будет использоваться в дальнейшем. Для получения дополнительной информации о проблеме, пожалуйста, проверьте советы по программированию Python Тима Уилсона: кредит и платежный калькулятор.
12 ответов:
8.833333333339
(или8.833333333333334
, результат106.00/12
) правильно округлены до двух знаков после запятой8.83
. Математически это звучит так, как будто вы хотите потолочные функция. Тот, что в Питонеmath
модуль называетсяceil
:import math v = 8.8333333333333339 print(math.ceil(v*100)/100) # -> 8.84
соответственно, функции пола и потолка обычно сопоставляют действительное число с самым большим предыдущим или самым маленьким следующим целым числом, которое имеет нулевые десятичные разряды - поэтому использовать их для 2 десятичных разрядов число сначала умножается на 102 (или 100), чтобы сдвинуть десятичную точку, а затем делится на нее впоследствии, чтобы компенсировать.
если вы не хотите использовать
math
модуль по какой-то причине вы можете использовать эту (минимально протестированную) реализацию, которую я только что написал:def ceiling(x): n = int(x) return n if n-1 < x <= n else n+1
как это относится к связанному проблема с кредитным и платежным калькулятором
от пример вывода оказывается, что они сгоняли ежемесячный платеж, который многие называют эффектом потолочной функции. Это значит, что каждый месяц чуть больше 1⁄12 из общей суммы выплачивается. Это сделало окончательный платеж немного меньше, чем обычно - оставляя оставшийся неоплаченный остаток только
8.76
.было бы одинаково справедливо использовать нормальное округление, производящее ежемесячный платеж из
8.83
и немного выше окончательный платеж8.87
. Однако в реальном мире люди обычно не любят, когда их платежи растут, поэтому округление каждого платежа является обычной практикой - оно также возвращает деньги кредитору быстрее.
Это нормально (и не имеет ничего общего с Python), потому что 8.83 не может быть представлен точно как двоичный float, так же как 1/3 не может быть представлена точно в десятичном формате (0.333333... до бесконечности).
Если вы хотите обеспечить абсолютную точность, вам нужен
decimal
модуль:>>> import decimal >>> a = decimal.Decimal("8.833333333339") >>> print(round(a,2)) 8.83
вы хотите использовать десятичный модуль, но вам также нужно указать режим округления. Вот пример:
>>> import decimal >>> decimal.Decimal('8.333333').quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_UP) Decimal('8.34') >>> decimal.Decimal('8.333333').quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_DOWN) Decimal('8.33') >>>
гораздо более простой способ-просто использовать функцию Round (). Вот вам пример.
total_price = float() price_1 = 2.99 price_2 = 0.99 total_price = price_1 + price_2
если бы вы распечатали total_price прямо сейчас, вы бы получили
3.9800000000000004
но если вы заключите его в круглую () функцию, как так
print(round(total_price,2))
выход равен
3.98
функция round () работает, принимая два параметра. Первый-это число, которое вы хотите округлить. Во-вторых, это количество десятичных знаков для округления.
Если вы округляете 8.8333333333339 до 2 десятичных знаков, правильный ответ-8.83, а не 8.84. Причина, по которой вы получили 8.83000000001, заключается в том, что 8.83-это число, которое не может быть правильно восстановлено в двоичном формате, и оно дает вам самый близкий. Если вы хотите напечатать его без всех нулей, сделайте так, как говорит VGE:
print "%.2f" % 8.833333333339 #(Replace number with the variable?)
Если вы хотите округлить, 8.84-это неправильный ответ. 8.833333333333 округлые-это не 8.83 8.84. Если вы хотите всегда округлять, то вы можете использовать математику.потолка. Сделайте оба в сочетании с форматированием строки, потому что округление числа с плавающей запятой само по себе не имеет смысла.
"%.2f" % (math.ceil(x * 100) / 100)
просто для протокола. Вы могли бы сделать это таким образом:
def roundno(no): return int(no//1 + ((no%1)/0.5)//1)
там, нет необходимости включает / импортирует
самый простой способ сделать это с помощью ниже функции, которая встроена
format()
например:
format(1.242563,".2f")
выход будет:
1.24
так же:
format(9.165654,".1f")
даст:
9.2
использовать
decimal
модуль:http://docs.python.org/library/decimal.html
Hier-это мое решение для круглой задачи up / down
>= .5 раунд АП
import math def _should_round_down(val: float): if val < 0: return ((val * -1) % 1) < 0.5 return (val % 1) < 0.5 def _round(val: float, ndigits=0): if ndigits > 0: val *= 10 ** (ndigits - 1) is_positive = val > 0 tmp_val = val if not is_positive: tmp_val *= -1 rounded_value = math.floor(tmp_val) if _should_round_down(val) else math.ceil(tmp_val) if not is_positive: rounded_value *= -1 if ndigits > 0: rounded_value /= 10 ** (ndigits - 1) return rounded_value # test # nr = 12.2548 # for digit in range(0, 4): # print("{} decimals : {} -> {}".format(digit, nr, _round(nr, digit))) # output # 0 decimals : 12.2548 -> 12 # 1 decimals : 12.2548 -> 12.0 # 2 decimals : 12.2548 -> 12.3 # 3 decimals : 12.2548 -> 12.25
вот простая функция, чтобы сделать это для вас::
def precision(num,x): return "{0:.xf}".format(round(num))
здесь , num-десятичное число x-это десятичное число до того места, где вы хотите округлить плавающее число
преимущество перед другими реализациями заключается в том, что он может заполнять нули в правом конце десятичного знака, чтобы сделать число deciaml до X десятичных знаков .
Пример 1:
precision(10.2,9)
вернутся 10.200000000 (до 9 dp )
Пример 2:
precision(10.2231,2)
будет возвращаться 10.22 (до 2 ДП )