如何将浮点数舍入到某个小数位?

时间:2010-12-23 12:13:26

标签: python floating-point

假设我有8.8333333333333339,我想将其转换为8.84。我怎样才能在Python中实现这一目标?

round(8.8333333333333339, 2)提供8.83而非8.84。我是Python新手或一般编程人员。

我不想将其打印为字符串,结果将被进一步使用。有关该问题的详细信息,请查看 Tim Wilson's Python Programming Tips: Loan and payment calculator

12 个答案:

答案 0 :(得分:94)

8.833333333339(或8.833333333333334106.00/12的结果)正确舍入到小数点后两位8.83。数学上听起来像你想要的是ceiling function。 Python的math模块中的一个名为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

这如何适用于链接的loan and payment calculator problem

screenshot of loan calculator output

从示例输出中看来,他们 向上舍入 每月付款,这就是很多人称之为天花板功能的效果。这意味着每月支付的金额略高于 1 / 12 。这使得最终付款比平时稍微小一点 - 剩余的未付余额仅为8.76

使用正常舍入产生8.83的每月付款和8.87的稍高的最终付款同样有效。然而,在现实世界中,人们通常不希望他们的付款增加,因此将每笔付款四舍五入是通常的做法 - 它还会更快地将钱返还给贷方。

答案 1 :(得分:62)

This is normal(并且与Python无关)因为8.83不能完全表示为二进制浮点数,正如1/3不能用十进制精确表示(0.333333 ... ad infinitum)。

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

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

答案 2 :(得分: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')
>>> 

答案 3 :(得分:11)

更简单的方法是简单地使用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()函数通过接受两个参数来工作。第一个是你要圆的数字。第二个是要舍入的小数位数。

答案 4 :(得分:7)

如果将8.8333333333339舍入为2位小数,则正确答案为8.83,而不是8.84。你得到8.83000000001的原因是8.83是一个无法用二进制正确表示的数字,它给你最接近的数字。如果你想在没有全零的情况下进行打印,请按照VGE的说法进行操作:

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

答案 5 :(得分:5)

如果你想圆,8.84是不正确的答案。 8.833333333333舍入为8.83而不是8.84。如果你想要总是向上舍入,那么你可以使用math.ceil。两者都与字符串格式组合,因为舍入浮点数本身没有意义。

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

答案 6 :(得分:3)

仅供记录。你可以这样做:

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

那里,不需要包含/导入

答案 7 :(得分:3)

最简单的方法是使用以下内置函数:

format()

例如:

format(1.242563,".2f")

输出结果为:

1.24

类似地:

format(9.165654,".1f")

会给:

9.2

答案 8 :(得分:1)

答案 9 :(得分:1)

以下是我对上下左右问题的解决方案

< .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

答案 10 :(得分: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(最多两位小数)

答案 11 :(得分:0)

我有此代码:

tax = (tax / 100) * price

然后是此代码:

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

一轮对我有用