如何将浮点数四舍五入到小数点后一位?


83

假设我有8.8333333333333339,我想将其转换为8.84。如何在Python中完成此操作?

round(8.8333333333333339, 2)给与8.838.84。我是Python或一般编程的新手。

我不想将其打印为字符串,结果将被进一步使用。有关此问题的更多信息,请查看Tim Wilson的Python编程技巧:贷款和付款计算器


4
round(8.8333333333333339,2)看起来会给出8.83永远不会给出8.84。
VGE 2010年

42
为什么是8.84?瞄准小数点后两位时,8.8333333 ...应四舍五入为8.83。
Tim Pietzcker 2010年


1
如果要打印该值,请使用打印“%.2f”%8.8333333333333339之类的格式。这将打印出值与2位
VGE

我编辑了标题,因为这是“ python round float”的早期结果,可能不是大多数人想要的。希望新标题可以使事情变得更清楚。
jpmc26 2015年

Answers:


100

8.833333333339(或8.833333333333334的结果106.00/12)正确舍入为小数点后两位8.83。数学上,这听起来像您想要的是天花板功能。Pythonmath模块中的一个名为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 ... ad infinitum)一样。

如果要确保绝对精度,则需要以下decimal模块:

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

如果您使用print函数/语句(取决于您的Python版本),则不会。
蒂姆·皮茨克

>>> 106.00/12 => 8.833333333333334
martineau 2010年

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舍入到两位小数,则正确答案是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是要舍入到浮点数的十进制数。

与其他实现相比的优势在于,它可以在小数点的右端填充零,以使deciaml数字最多x个小数位。

范例1:

precision(10.2, 9)

将返回

10.200000000(最多9个小数点)

范例2:

precision(10.2231, 2)

将返回

10.22(最多两个小数点)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.