Python - 求2的1000次方的各位数字之和?

5

这是我的Python代码,但根据projecteuler.net的要求给出的答案是不正确的。

a = 2**1000
total = 0
while a >= 1:
    temp = a % 10
    total = total + temp
    a = int(a/10)
print(total)

它输出了1189。我犯了什么错误吗?

点击这里查看。 - Jeroen Heier
@abccd 那个问题是相关的,答案和评论中有很好的信息,但我认为它与这个问题不够接近,不能将其用作重复目标。 - PM 2Ring
@PM2Ring,你的回答很好。当我留下这个链接时,我希望看看社区是否认为它是一个重复的问题,如果不是,那么就是一个相关的帖子。我想裁决(至少由其他两名投票者)是它是一个足够接近的重复问题。请随意发起重新开放投票 :) - Taku
@abccd 我可以自己重新打开它。虽然我不太介意别人想用那个重复的目标关闭它,但如果有更好的匹配问题作为目标,我会更喜欢的。 - PM 2Ring
1个回答

7
您的逻辑没有问题。问题在于2 ** 1000对于所有数字来说太大了,不能全部适合一个浮点数,因此当您执行a = int(a/10)时,数字会被四舍五入。Python float只有53位精度,您可以在官方教程文章:浮点算术:问题和限制以及维基百科: 双精度浮点格式中了解更多相关信息。还可以查看浮点数运算是否有问题?
这是2 ** 1000

10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376

但是print(format(2**1000 / 10, 'f'))给我们的结果是:

1071508607186267380429101388171324322483904737701556012694158454746129413355810495130824665231870799934327252763807170417136096893411236061781867579266085792026680021578208129860941078404632071895251811587214122307926025420797364998626502669722909817741077261714977537247847201331018951634334519394304.000000

您可以看到,在10715086071862673之后,数字开始出现错误。
因此,您需要使用整数运算,在Python中具有任意精度(仅受Python可以访问的内存限制)。要做到这一点,请使用//地板除法运算符。
a = 2**1000
total = 0
while a >= 1:
    temp = a % 10
    total = total + temp
    a = a // 10
print(total)

输出

1366

我们可以通过使用增量赋值运算符来简化该代码。
a = 2**1000
total = 0
while a:
    total += a % 10
    a //= 10
print(total)

这里有一个更快的方法。将a转换为字符串,然后将每个数字再次转换为int并求和。我使用位移来计算a,因为它比指数运算更快。
print(sum(int(u) for u in str(1 << 1000)))

1
@J...S:Python中的整数是任意精度的。 - user2357112
@DillonDavis 意味着会有精度误差或其他什么吗? - J...S
@PM2Ring 我现在明白了。但是你能告诉我为什么 float 版本不同吗? - J...S
3
由于浮点数只能精确地保存 53 位小数,这不足以准确表示一个有 1001 位的数字。 - PM 2Ring
@tripleee 好主意,我添加了一些更多的信息和一些链接,但我不想把这个答案变成一个关于浮点数的教程。 - PM 2Ring
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接