Python - Project Euler#80,理解错误

时间:2016-06-08 15:38:08

标签: python decimal rounding precision square

项目欧拉问题#80似乎很简单:

https://projecteuler.net/problem=80

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

Dim rngTest As Range
Dim shtTest As Worksheet

For Each shtTest In ThisWorkbook.Sheets
    With shtTest
        .Range("m10").Value = "hello"
    End With
    shtTest.Activate
    Set rngTest = [M5]
    rngTest.Select
Next shtTest

我返回40308,据我所知,这是正确的答案。对于我返回的前十个自然数的平方根的数字和:

0 475 441 0 472 470 397 463 0 456

这里的错误在哪里?我认为这取决于某种舍入误差,但我似乎无法解决这个问题。

2 个答案:

答案 0 :(得分:3)

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

  

首先,100位数包括小数点右侧和左侧的数字。

     

其次,请确保计算的数字比避免舍入错误所需的数字更多,因为它会影响某些数字。

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 :(得分:2)

你犯了两个错误,这些错误相互抵消了示例案例。

  1. 您没有计入第一位1
  2. 您将精度设置得太低了一位数。最后一位数字几乎总是包含一些舍入误差。 sqrt(2)的第100和第101位数字为27,因此当您使用prec=100时,它会向上舍入到3,以弥补第一个错误。
  3. 顺便说一下。有一个简单的实施。 Decimal对象有as_tuple()方法:

      

    返回数字的命名元组表示: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”。