Python中小数的精度

时间:2014-01-18 22:30:59

标签: python decimal precision

我不是指精确度,因为小数点后显示的数字是多少。我的意思是精确度,因为我想在这个象形文字功能中使用的十进制数字仍然比它应该是十分之一。我尝试过使用多种不同的策略,包括导入十进制模块。这是我试图使用的功能。

values = [('tens', 10), ('fives', 5), ('ones', 1), ('tenths', 0.1)]

def get_digits(num):
    num = int(num * 10)
    num = float(num) / 10

    output_dict = {}
    for place, value in values:
        output_dict[place] = int(num // value)
        num = num % value

    return output_dict

使用get_digits(277.9),产生{'tens': 27, 'ones': 2, 'tenths': 8, 'fives': 1}

我需要它来说{'tens': 27, 'ones': 2, 'tenths': 9, 'fives': 1}

通过在填充字典后将十分之一加1来修复它不起作用,因为不是每个小数都不精确地出现。

get_digits(277.6)返回{'fives': 1, 'tenths': 6, 'tens': 27, 'ones': 2}

我一直在寻找答案的论坛,但没有得到它。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:5)

正如我在评论中试图解释的那样,问题在于您使用的是浮点数。

有关浮点的详细信息,请参阅12

问题在于277.9

存储为277.9,而是“非常接近”:

print('%.40f' % a)
277.8999999999999772626324556767940521240234

解决方案不是使用一些任意的启发式方法来判断数学是否略微偏离并尝试纠正它。我们 知道 数学略有偏差 - 这是浮点数给我们的礼物和诅咒。

真正的解决方案是使用定点数学,例如,使用Python的decimal模块。


修改

from decimal import Decimal

values = [
    ('tens',   Decimal(10)),
    ('fives',  Decimal(5)),
    ('ones',   Decimal(1)),
    ('tenths', Decimal('0.1'))
]

def get_digits(num):
    output_dict = {}
    for place, value in values:
        output_dict[place] = int(num // value)  # Cast from Decimal to int
        num = num % value
    return output_dict

num = Decimal('277.9')
print(get_digits(num))
# {'tens': 27, 'ones': 2, 'tenths': 9, 'fives': 1}

num = Decimal('277.6')
print(get_digits(num))
#{'tens': 27, 'ones': 2, 'tenths': 6, 'fives': 1}

以上代码与您的代码非常相似,但使用的是Python的十进制模块。不需要启发式检查。代码正常工作,因为小数字准确表示。