如何将浮点数向上舍入到特定的小数位?
假设我有一个数字 8.8333333333333339
,我想把它转换成 8.84
。在Python中我该怎么做呢?
用 round(8.8333333333333339, 2)
这个方法得到的结果是 8.83
,而不是我想要的 8.84
。我对Python或者编程都还很陌生。
我不想把它打印成字符串,因为我还需要用这个结果做其他事情。如果想了解更多关于这个问题的信息,可以查看 Tim Wilson的Python编程小贴士:贷款和支付计算器。
12 个回答
你想使用decimal模块,但同时也需要指定舍入的方式。下面是一个例子:
>>> 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')
>>>
这很正常(和Python没有关系),因为8.83这个数字不能被准确地表示为二进制浮点数,就像1/3在十进制中也不能被准确表示(它是0.333333...,无限循环下去)。
如果你想确保绝对的精确度,你需要使用decimal
模块:
>>> import decimal
>>> a = decimal.Decimal("8.833333333339")
>>> print(round(a,2))
8.83
8.833333333339
(或者 8.833333333333334
,这是 106.00/12
的结果)四舍五入到小数点后两位是 8.83
。从数学上讲,你想要的似乎是一个向上取整的函数。在Python的 math
模块中,这个函数叫做 ceil
:
import math
v = 8.8333333333333339
print(math.ceil(v*100)/100) # -> 8.84
一般来说,向下取整和向上取整的函数会把一个实数映射到它前面最大的整数或后面最小的整数,这些整数没有小数部分。为了用它们处理小数点后两位,首先要把这个数字乘以102(也就是100),这样小数点就会移动,然后再除以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
。不过在现实生活中,人们通常不喜欢还款金额增加,所以每次还款向上取整是常见的做法——这也能更快地把钱还给贷款方。