Як округлити число з плаваючою комою до певного знака після коми?


83

Припустимо, у мене є 8.8333333333333339, і я хочу перетворити його на 8.84. Як я можу це зробити в Python?

round(8.8333333333333339, 2)дає 8.83і ні 8.84. Я новачок у Python чи програмуванні загалом.

Я не хочу друкувати його як рядок, і результат буде використаний далі. Щоб отримати докладнішу інформацію про проблему, перегляньте підказки програмування Python Тіма Вільсона: Калькулятор позик та платежів .


4
раунд (8.8333333333333339, 2) дасть 8.83 ніколи 8.84, здається.
VGE

42
Чому 8,84? 8.8333333 ... слід округляти до 8.83, коли націлюєтеся на два знаки після коми.
Тім Пітцкер,


1
якщо ви хочете надрукувати значення, використовуйте такий формат, як друк "% .2f"% 8.8333333333333339. при цьому значення буде надруковано двозначним числом
VGE

Я відредагував заголовок, оскільки це з’являється як ранній результат для "python round float", і це, мабуть, не те, що шукає більшість людей. Сподіваємось, нова назва робить речі більш зрозумілими.
jpmc26,

Відповіді:


100

8.833333333339(або 8.833333333333334результат 106.00/12) правильно округлено до двох знаків після коми 8.83. Математично це схоже на те, що ви хочете - це функція стелі . Назва в mathмодулі Python називається ceil:

import math

v = 8.8333333333333339
print(math.ceil(v*100)/100)  # -> 8.84

Відповідно, функції підлоги та стелі, як правило, відображають дійсне число до найбільшого попереднього або найменшого наступного цілого числа, що має нуль десяткових знаків - тому, щоб використовувати їх для 2 знаків після коми, число спочатку множиться на 10 2 (або 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. Однак у реальному світі люди зазвичай не люблять, щоб їхні платежі зростали, тому округлення кожного платежу є звичайною практикою - воно також швидше повертає гроші позикодавцю.


67

Це нормально (і не має нічого спільного з Python), оскільки 8,83 неможливо представити точно як двійковий плаваючий знак, так само як 1/3 не може бути представлений точно в десятковому порядку (0,333333 ... до кінця).

Якщо ви хочете забезпечити абсолютну точність, вам потрібен decimalмодуль:

>>> import decimal
>>> a = decimal.Decimal("8.833333333339")
>>> print(round(a,2))
8.83

Ні, якщо ви використовуєте printфункцію / оператор (залежно від вашої версії Python).
Тім Пітцкер,

>>> 106.00/12 => 8.833333333333334
Мартіно

22

Ви хочете використовувати десятковий модуль, але вам також потрібно вказати режим округлення. Ось приклад:

>>> 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')
>>> 

13

Набагато простіший спосіб - це просто використовувати функцію round (). Ось приклад.

total_price = float()
price_1 = 2.99
price_2 = 0.99
total_price = price_1 + price_2

Якби зараз ви роздруковували total_price, то отримали б

3.9800000000000004

Але якщо ви вкладете його у функцію round () приблизно так

print(round(total_price,2))

Вихід дорівнює

3.98

Функція round () працює, приймаючи два параметри. Перший - це число, яке потрібно округлити. Другий - кількість десяткових знаків, до яких потрібно округлити.


7

Якщо округлити 8,8333333333339 до 2 знаків після коми, правильна відповідь - 8,83, а не 8,84. Причина, по якій ви отримали 8,83000000001, полягає в тому, що 8,83 - це число, яке неможливо правильно представити у двійковому вигляді, і воно дає вам найближче. Якщо ви хочете надрукувати його без усіх нулів, зробіть, як каже VGE:

print "%.2f" % 8.833333333339   #(Replace number with the variable?)

6

Найпростіший спосіб це зробити, використовуючи вбудовану нижче функцію:

format()

Наприклад:

format(1.242563,".2f")

Результатом буде:

1.24

Аналогічно:

format(9.165654,".1f")

дав би:

9.2

Відповідь у форматі була дана у 2010 році тут . Ви могли б натомість оновити цю відповідь.
ZF007

5

Якщо ви хочете округлити, 8,84 - неправильна відповідь. 8,833333333333 округлено - 8,83, а не 8,84. Якщо ви хочете завжди округляти, тоді ви можете використовувати math.ceil. Зробіть обидва варіанти в поєднанні з форматуванням рядків, оскільки округлення числа з плаваючою точкою не має сенсу.

"%.2f" % (math.ceil(x * 100) / 100)

4

Просто для запису. Ви можете зробити це таким чином:

def roundno(no):
    return int(no//1 + ((no%1)/0.5)//1)

Там немає необхідності включати / імпортувати


2

Ось моє рішення проблеми округлення вгору / вниз

< .5  round down

> = .5  round up

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

1

У мене є такий код:

tax = (tax / 100) * price

а потім цей код:

tax = round((tax / 100) * price, 2)

раунд спрацював у мене


Ви вирішили мою проблему. Я міг лише округлитись цим. Більше нічого не працювало. renewal_percentage=round(df_x_renewal_count/df_all_count*100)
Kierk


0

Ось проста функція, яка робить це за вас:

def precision(num,x):
    return "{0:.xf}".format(round(num))

Тут num - десяткове число. x - десяткове число до місця, де потрібно округлити плаваюче число.

Перевага перед іншою реалізацією полягає в тому, що він може заповнити нулі в правому кінці десяткової коми, щоб зробити число децималів до x знаків після коми.

Приклад 1:

precision(10.2, 9)

повернеться

10.200000000 (до 9 знаків після коми)

Приклад 2:

precision(10.2231, 2)

повернеться

10,22 (до двох знаків після коми)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.