Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 减去截断的数字:结果为';t截断?_Python_Truncated - Fatal编程技术网

Python 减去截断的数字:结果为';t截断?

Python 减去截断的数字:结果为';t截断?,python,truncated,Python,Truncated,我正在尝试创建一个函数,该函数将根据指定的百分比(好的,预算)将数字划分为类别 我使用了分割的浮点,从web上获取了一个测试截断函数,并截断了第一百位之后的所有内容。这是为了防止所有类别的总和大于初始金额。然后,我从初始金额中减去类别的总和,得到一个“余数”,在我的示例中应该是0.03,或3美分 def budget_calc(amount): budget = {"t":0.10, "c":0.50, "s":0.20,

我正在尝试创建一个函数,该函数将根据指定的百分比(好的,预算)将数字划分为类别

我使用了分割的浮点,从web上获取了一个测试截断函数,并截断了第一百位之后的所有内容。这是为了防止所有类别的总和大于初始金额。然后,我从初始金额中减去类别的总和,得到一个“余数”,在我的示例中应该是0.03,或3美分

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
包实现您想要的功能。