Python项目Euler#80,了解

2024-05-16 11:31:21 发布

您现在位置:Python中文网/ 问答频道 /正文

Project Euler问题#80似乎很简单:

https://projecteuler.net/problem=80

使用十进制模块计算平方根至给定精度:

from decimal import Decimal, localcontext

def prob80():
    total = 0
    for x in range(1,100):
        with localcontext() as ctx:
            ctx.prec = 100
            total+=sum([int(i) for i in str(Decimal(x).sqrt())[2:]])
    return total
print prob80()

我返回40308,我知道这有点偏离正确答案。对于前十个自然数平方根的数字和,我返回:

0 475 441 0 472 470 397 463 0 456个

哪里出错了?我想这是由于某种舍入误差,但我似乎无法解决。在


Tags: 模块inhttpsprojectfornet精度total
2条回答

http://blog.dreamshire.com/project-euler-80-solution/

First, the 100 digits include digits to the right and left of the decimal.

Second, make sure to calculate more digits than are necessary to avoid rounding errors as it affects some of the numbers.

from decimal import Decimal, localcontext

def prob80():
    total = 0
    for x in range(1,100):
        print x
        with localcontext() as ctx:
            ctx.prec = 105
            if len(str(Decimal(x).sqrt())) == 1:
                total+=0
            else:
                a = sum([int(i) for i in str(Decimal(x).sqrt())[2:101]])+int(str(Decimal(x).sqrt())[0])
                total+=a
    return total
print prob80()

你犯了两个错误,这两个错误相互抵消了。在

  1. 您没有用第一位数字1
  2. 你把精度设得太低了一位数。最后一个数字几乎总是包含一些舍入误差。sqrt(2)的第100位和第101位是27,所以当你使用prec=100时,它被四舍五入到{},弥补了第一个错误。在

顺便说一句,有一个简单明了的实现。Decimal对象具有^{}方法:

Return a named tuple representation of the number: DecimalTuple(sign, digits, exponent).

所以你可以选择:

decimal.getcontext().prec = 101
i = 2
sum(decimal.Decimal(i).sqrt().as_tuple()[1][:100]) # [1] is `digits`; [:100] are 1st 100

不需要字符串转换或“iffing”。在

相关问题 更多 >