在 python 中转换为浮点数或十进制时值不完全匹配

Values not matching exactly when converting to float or decimal in python

提问人:Gaurav Kumar 提问时间:7/30/2020 更新时间:7/30/2020 访问量:491

问:

转换为浮点数或十进制时,值不正确。 以下是一些示例:

"{0:.20f}".format(0.1) = '0.10000000000000000555'
"{0:.20f}".format(1/3) = '0.33333333333333331483'
Decimal(2.4) = Decimal('2.399999999999999911182158029987476766109466552734375')

上述行为在四舍五入数字时会导致问题。例如 我预计 round(6.345, 2) 等于 6.35,但结果是 6.34,可能是因为 Decimal(6.345) 的计算结果为 6.3449999999999999975131004248396493494510650634765625,比 6.35 更接近 6.34。

为什么会这样?解决方法是什么?

Python 十进制 浮点精度

评论

0赞 Safwan Samsudeen 7/30/2020
有什么作用?你是说 ?Decimalfloat
0赞 ubaid shaikh 7/30/2020
@SafwanSamsudeen 它来自十进制模块。Like - 从十进制导入十进制
2赞 Nicolas Gervais 7/30/2020
这回答了你的问题吗?浮点数学坏了吗?

答:

0赞 MisterNox 7/30/2020 #1

我不知道这是否是你要找的,但你可以编写自己的 round 函数来执行你想要的 round 过程。这里有一个例子,可能不是我最好的工作,肯定还有更多的pythonic方法,但它至少是你可以建立的东西:

num = 6.345

def custom_round(number, spaces=0):
    if isinstance(num, int):
        return num

    integer, decimal = str(number).split('.')

    if spaces >= len(decimal):
        return num
    elif spaces == 0:
        if int(decimal[:1]) >= 5:
            return int(integer) + 1
        else:
            return int(integer)
    elif int(decimal[spaces : spaces + 1]) >= 5:
        return float(integer + "." + str(int(decimal[:spaces]) + 1))
    else:
        return float(integer  + "." + str(int(decimal[:spaces])))

print(custom_round(num, 1))
# 6.3
print(custom_round(num, 2))
# 6.35
0赞 ubaid shaikh 7/30/2020 #2

这可能是一种解决方法。

import math
from decimal import Decimal
print("{0:.20f}".format(0.1))
print("{0:.20f}".format(1/3))

def round_half_up(n, decimals=0):
    multiplier = 10 ** decimals
    return math.floor(n*multiplier + 0.5) / multiplier
num=6.345

print(round(Decimal(str(num)),2))
print(round_half_up(num,2))

输出:

0.10000000000000000555                                                                                                  
0.33333333333333331483                                                                                                  
6.34                                                                                                                    
6.35

参考: https://realpython.com/python-rounding/#rounding-half-up

如果这不能满足您的需求,那么我建议使用分数,例如您可以使用 a=[6345,1000] 或只是 a=[6345,3](3 表示 1o^3) 而不是 a=6.345 并计算最后答案的浮点值。但是,您将不得不手动为您执行的所有算术运算创建函数。

这是一个建议使用 https://stackoverflow.com/a/53821658/11474769 的答案fractions.Fraction

我没有任何经验,但从文档来看,它似乎可以证明在这种情况下是有用的。 链接到文档 https://docs.python.org/3/library/fractions.htmlfractions.Fraction

请看一下。

评论

0赞 superb rain 7/30/2020
您也可以将 Decimal 四舍五入为 .decimal.getcontext().rounding = decimal.ROUND_HALF_UP