我试图将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]
我该如何解决这个问题?
答案 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