有没有另一种方法可以在没有calliground()的情况下减少小数点后10位后的数字?
我想创建一个函数,无论接收到什么数字作为输入,它都会在第 10 个数字之后截断(不是舍入,这可能需要更高的小数点)每个数字。它通常工作正常,但如果我用这样的数字调用函数:
1234567.123456789123456789
它返回:1234567.1234567892
而不是 1234567.1234567891,正如预期的那样。
def cut_to_10(number):
number = str(number)
j = 0
if "." in number:
for i in number:
j += 1
if i == ".":
before_dot = number[:j - 1]
after_dot = number[j:]
if len(after_dot) > 10:
after_dot = after_dot[:10]
return float(before_dot + "." + after_dot)
if "." not in number:
return round(float(number), 10)
编辑 1:
也试过这个,返回了同样的意外结果。
import numpy as np
def cut_to_10(number):
return np.floor(number * 1e10) / 1e10
编辑2:
考虑到 ShadowRanger 给出的惊人解释,但是,考虑到我需要更多的天花板精度而不是地板精度,并且考虑到我仍然必须使用浮动,我决定改变
return float(before_dot + "." + after_dot)
到
return float(before_dot + "." + after_dot) - 2e-10
它工作正常。1e-10 没用。
回答
1234567.123456789123456789不是实际的float. 您可以键入它,但它会变成 1234567.1234567892,最接近的可表示float值;舍入发生在您实际调用之前round。
>>> 1234567.123456789123456789
1234567.1234567892
如果你需要那么高的精度,你需要移动到decimal.Decimal,它会工作得很好:
>>> decimal.Decimal('1234567.123456789123456789')
Decimal('1234567.123456789123456789')
>>> round(_, 10)
Decimal('1234567.1234567891')
只是不要转换回float,因为1234567.1234567891它不存在(如果确实存在,那就是1234567.123456789123456789会产生的),然后您将回到从1234567.1234567892.
THE END
二维码