【问题标题】:Python - Project Euler #80, understanding the errorPython - Project Euler #80,了解错误
【发布时间】:2016-06-08 15:38:07
【问题描述】:

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

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

【问题讨论】:

  • 如果您怀疑舍入错误,您应该以不同的方式处理具有整数根的 rumbers。意味着完全无视它们,不希望它们的前 100 个十进制数字加起来为 0
  • 如果我忽略整数根的数字,我会返回相同的结果
  • 即squares = [1,4,9,16,25,36,49,64,81] for x in range(1,100): if x not in squares:

标签: python decimal rounding precision square


【解决方案1】:

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()

【讨论】:

  • 嗯,你不是曾经说过一个人必须计算第一个数字,但是对于自然数的平方你不计算它吗? 4(以10为基数)的所有十进制数字的总和是2,或者我错过了什么? IE。应该没有if
  • 4(以10为底)的平方根的所有十进制数字的总和当然是2
  • 问题只对无理数求和。
  • 哦,这不是在问题中发布的。我现在明白了。谢谢。
【解决方案2】:

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

  1. 您没有计入第一位1
  2. 您将精度设置得太低了一位。最后一位几乎总是包含一些舍入误差。 sqrt(2) 的第 100 位和第 101 位是 27,所以当您使用 prec=100 时,它会向上取整为 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”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多