代码之家  ›  专栏  ›  技术社区  ›  grokus

项目Euler_101-如何解决numpy多项式溢出?

  •  2
  • grokus  · 技术社区  · 15 年前

    Project Euler #101

    我刚开始学麻木,到目前为止我觉得很简单。

    我遇到的一件事是,当我计算多项式时,结果是一个Int32,所以会发生溢出。

    u = numpy.poly1d([1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1])
    for i in xrange(1, 11):
        print(i, u(i))
    

    结果是:

    (1, 1)
    (2, 683)
    (3, 44287)
    (4, 838861)
    (5, 8138021)
    (6, 51828151)
    (7, 247165843)
    (8, 954437177)
    (9, -1156861335)
    (10, 500974499)
    

    最后两项显然不正确。

    我能想到的是将系数因子分解为100。

    u = numpy.poly1d([0.01, -0.01, 0.01, -0.01, 0.01, -0.01, 0.01, -0.01, 0.01, -0.01, 0.01])
    for i in xrange(1, 11):
        print(i, int(u(i) * 100))
    

    这次结果是正确的

    (1, 1)
    (2, 682)
    (3, 44286)
    (4, 838860)
    (5, 8138020)
    (6, 51828151)
    (7, 247165843)
    (8, 954437177)
    (9, 3138105961L)
    (10, 9090909091L)
    

    有更好的方法吗?numpy允许我更改数据类型吗?谢谢。

    2 回复  |  直到 10 年前
        1
  •  4
  •   interjay    15 年前

    不是100的比例缩放起了作用,而是给出的数字是浮点数而不是整数,因此具有更高的范围。由于浮点计算,您已经看到,计算中引入了一些不准确的地方。

    您可以这样手动指定类型:

    u = numpy.poly1d(numpy.array([1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1], dtype=numpy.int64))
    

    这个问题的计算适合64位整数,所以这是可行的。

    列出了支持的类型 here .

        2
  •  0
  •   Andrew Dalke    15 年前

    在我写这篇文章的时候,Interjay给出了一个更好的答案,但我想你还是需要另一个选择。

    下面是您展示的示例的简单实现:

    class Poly(object):
        def __init__(self, coefficients):
            assert len(coefficients) > 0
            self.coefficients = coefficients
        def __call__(self, value):
            total = self.coefficients[0]
            for c in self.coefficients[1:]:
                total = total * value + c
            return total
    

    还有一些测试

    assert Poly([5])(1) == 5
    assert Poly([7])(1) == 7
    assert Poly([2,3])(5) == 13
    assert Poly([1,0,0,0,0])(-2) == 16
    u = Poly([1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1])
    for i in range(1, 11):
        print (i, u(i))
    

    相当无用的

    assert Poly([2,"!"])("Hello ") == "Hello Hello !"