Python 减去截断的数字:结果为';t截断?
我正在尝试创建一个函数,该函数将根据指定的百分比(好的,预算)将数字划分为类别 我使用了分割的浮点,从web上获取了一个测试截断函数,并截断了第一百位之后的所有内容。这是为了防止所有类别的总和大于初始金额。然后,我从初始金额中减去类别的总和,得到一个“余数”,在我的示例中应该是0.03,或3美分Python 减去截断的数字:结果为';t截断?,python,truncated,Python,Truncated,我正在尝试创建一个函数,该函数将根据指定的百分比(好的,预算)将数字划分为类别 我使用了分割的浮点,从web上获取了一个测试截断函数,并截断了第一百位之后的所有内容。这是为了防止所有类别的总和大于初始金额。然后,我从初始金额中减去类别的总和,得到一个“余数”,在我的示例中应该是0.03,或3美分 def budget_calc(amount): budget = {"t":0.10, "c":0.50, "s":0.20,
def budget_calc(amount):
budget = {"t":0.10,
"c":0.50,
"s":0.20,
"e":0.05,
"c/m":0.05,
"tr":0.05,
"o":0.03,
"g/d":0.02}
def truncate(x, d):
return int(x*(10.0**d))/(10.0**d)
def multp(key):
cate = truncate(amount * budget.get(key), 2)
return cate
new_amounts = {'t': multp('t'),
'c': multp('c'),
's': multp('s'),
'e': multp('e'),
'c/m': multp('c/m'),
'tr': multp('tr'),
'o': multp('o'),
'g/d': multp('g/d')}
remainder = amount - sum(new_amounts.values())
new_amounts.update(remainder = remainder)
return new_amounts
这就是我得到的:
budget_calc(148.72)
{'t': 14.87,
'c': 74.36,
's': 29.74,
'e': 7.43,
'c/m': 7.43,
'tr': 7.43,
'o': 4.46,
'g/d': 2.97,
'remainder': 0.029999999999972715} #<-- this number should only contain two decimal points
预算计算(148.72)
{'t':14.87,
c分:74.36分,
“s”:29.74,
“e”:7.43,
“c/m”:7.43,
‘tr’:7.43,
“o”:4.46,
g/d:2.97,
“余数”:0.0299999972715}#您从未将
truncate
应用于余数
计算,您只是将截断的数字求和并减去它们。sum
中的每一次加法都可能会出现一个小的精度问题,而减法则会引入另一个精度问题,截断结果将导致严重的问题(因为截断时,即使稍微减小值的错误也会导致巨大的错误)。如果你想始终如一地取整它,你必须每次都取整它。我还建议使用math.fsum
来减少求和时的错误:
>>> d = {'t': 14.87,
'c': 74.36,
's': 29.74,
'e': 7.43,
'c/m': 7.43,
'tr': 7.43,
'o': 4.46,
'g/d': 2.97}
>>> import math
>>> sum(d.values()) # Loses precision
148.69000000000003
>>> math.fsum(d.values()) # More accurate!
148.69
>>> 148.72 - sum(d.values()) # Already lost precision, so result wrong
0.029999999999972715
>>> 148.72 - math.fsum(d.values()) # Sadly, even with accurate fsum, final subtraction is "wrong"
0.030000000000001137
>>> round(148.72 - math.fsum(d.values()), 2) # But we can always round it off
0.03
综上所述,尝试使用
float
s来实现这一点本身就容易出错<代码>浮点精度以二进制表示,您需要十进制精度。如果您需要十进制精度,我强烈建议您使用具有一百万个旋钮的指针,以使其完全按照您希望的方式运行。这是由于浮点计算的不精确性,就像
0.1 + 0.2 = 0.30000000000000004
在javascript中
你可以在这里找到更多的信息
一个解决方案是舍入而不是截断,同时舍入提醒。您可能需要阅读此文章以获得对(二进制)浮点算法的基本理解。您可以使用decimal
包实现您想要的功能。