Python中的小数位数

时间:2015-04-03 05:11:17

标签: python algorithm

我试图将1/n的所有小数位放入Python的列表中。

def dec(n):

    result = float(1) / n
    while (result >= 1):
        result = result - 1

    while (result != 0):
        result = result * 10
        decimals = int(result)
        yield(decimals)
        result = result - decimals

然而,当我尝试list(dec(3))时,它并没有给我一个完整的3个列表,而是[3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 7, 2]

我该如何解决这个问题?

4 个答案:

答案 0 :(得分:3)

由于Python浮点数以二进制表示,因此分数的浮点表示不仅仅是不精确的 - 十进制近似通常也是不精确的 - 但是以反直觉的方式不精确。我们习惯于将像1/3这样的分数近似为0.3333333333或33333333333/10 ** 10(假设10位有效数字)。但是,Python使用的二进制浮点数表示为具有二次幂分母的分数。在此表示中,1/3近似为6004799503160661/2 ** 54,输出中的数字来自该分数。

要计算1/3分数十进制近似值的数字,请导入decimal模块并将float(1)替换为decimal.Decimal(1)Decimal type的设计目的是支持你在这里尝试做的事情,即获得与学校教授的算法相同的铅笔纸计算结果。

Decimal实例当然包含有限数量的数字,这些数字是无限重复的1/3。为了能够无限制地访问数字,请导入fractions并使用fractions.Fraction()。在这种情况下,生成器生成的序列将是无限的,您将无法将其转换为列表,但您仍然可以迭代它并根据需要分析它。

答案 1 :(得分:0)

我假设您使用的是Python 3,因为您只有一个" /"。您注意到float(1)/ 3 * 100000000 = 33333333.333333332。这很可能是由于小数部分的二进制表示的变幻莫测,因为你的浮点宽度精度不足。

因此,您最好将其作为字符串处理,并将其转换为列表:

list(str(float(1)/3))[2:]

['3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3']

答案 2 :(得分:0)

您正试图将有理数作为repeating decimal。你需要知道:

  

每个有理数都是终止或重复的小数。

因此您不需要存储所有数字(非重复部分和重复部分)。另一个要点是,如果你有m/n,那么你的重复部分的长度最长为n-1

因为你基本上要求项目Euler 26任务的解决方案,我不会发布它,而是会给你一个link with some explanation

答案 3 :(得分:0)

浮点运算必然不准确。精确计算数字的一种方法是使用你在学校学到的分割算法。

这是一个实现:

def dec(n):
    v = 1
    while v:
        v *= 10
        yield v // n
        v %= n

您可以像这样测试它,它显示前1/40,1 / 5,1 / 7和1/11的40位数字。

import itertools

for i in [3, 5, 7, 11]:
    print '1/%d = 0.%s' % (i, ''.join(map(str, itertools.islice(dec(i), 40))))

输出结果为:

1/3 = 0.3333333333333333333333333333333333333333
1/5 = 0.2
1/7 = 0.1428571428571428571428571428571428571428
1/11 = 0.0909090909090909090909090909090909090909