2

我有以下代码来计算n!

import numpy as np

print "n! (for n<31)"
print

n = input("Enter n: ")

lst = []
for i in range(1,n+1):
    lst.append(i)

print lst     #Just to see if the program is working

print "n!: ", np.prod(lst)

但是,对于某些数字,程序会返回负值。

例如。以下是我运行 n = 20 时来自控制台的内容:

n! (for n<31)

Enter n: 20
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
n!:  -2102132736

它也发生在 n = 32 但是,该程序确实适用于其他数字,例如。3!返回 6,因为它应该。

有人可以解释一下。

4

3 回答 3

3

这是 numpy 的 prod 函数的文档链接:

numpy.prod

如果您转到该页面的底部,您会看到最后一个示例说明当 x(函数的给定参数)是无符号整数时,返回的结果是默认平台整数。因此,当结果超过可以存储在 32 位整数中的结果时,numpy 不会将结果转换为 long 类型,就像 python 通常那样。所以你得到整数溢出。

如果你声明一个函数:

def fact(n): return 1 if n == 1 else (n * fact(n-1))

并做:

fact(20)

你得到:

2432902008176640000L

这是 20! 的正确值。

顺便说一句,做:

lst = []
for i in range(1,n+1):
    lst.append(i)

不理想。Python 的 range 函数可以轻松做到这一点!尝试:

lst = range(1, n + 1)

你已经在你的 for 循环中这样做了!您可以在解释器中对其进行测试:

>>> range(1, 20 + 1)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
于 2013-08-14T10:06:04.137 回答
1

我强烈怀疑 Numpy 正在创建一个 32 位整数数组。

因此,当 n! 时,您会看到整数溢出!大于 32 位整数的限制。

尝试:

 print "n!: ", np.prod(lst, dtype=np.uint64)
于 2013-08-14T09:43:47.083 回答
0

正如我在评论中所写,这是一个 32 位问题。如果你有一个64位系统,你仍然可以计算到20!

这是一个没有 numpy 的解决方案,使用 python 内置类型,可以非常安全地处理此类问题:

def factorial(n):
    result = 1
    for i in range(1, n+1):
        result *= i
    return result

n = input("n! (for n<31)\n\nEnter n: ")
print("n!: %d" % factorial(n))

这是一个递归函数,可以改变你的想法;-)

def factorial_r(n):
    if n < 2:
        return 1
    return n * factorial_r(n-1)

n = input("n! (for n<31)\n\nEnter n: ")
print("n!: %d" % factorial_r(n))
于 2013-08-14T09:45:58.767 回答