使用Numpy生成杨辉三角时n≥13出现负值的原因及解决方法
问题原因与修复方案
错误原因
- 你使用了Numpy默认的
int类型,它本质是32位有符号整数,最大值为2147483647。 - 当计算到13的阶乘时,13! = 6227020800,已经超过32位整数的上限,触发了整数溢出。溢出后数值会按照补码规则循环,变成负数,直接导致后续组合数计算完全错误。
修复方法
以下是几种可行的修复方式,按效率和可靠性排序:
方法1:利用杨辉三角递推性质(最优)
杨辉三角的核心规律是:每一行的元素等于上一行相邻两个元素之和,完全不需要计算阶乘,既高效又彻底避免溢出问题。
修改后的代码:
def print_pascal_triangle(rows): print(1) prev_line = [1] for _ in range(1, rows): current_line = [1] for i in range(len(prev_line)-1): current_line.append(prev_line[i] + prev_line[i+1]) current_line.append(1) print(*current_line, sep=" ") prev_line = current_line # 打印13行(包含第一行) print_pascal_triangle(13)
方法2:改用Python原生整数计算阶乘
Python的原生int是任意精度的,不会出现溢出问题,完全可以不用Numpy来做阶乘计算:
修改后的binomial函数:
def binomial(n, k): def factorial(x): res = 1 for num in range(1, x+1): res *= num return res return factorial(n) // (factorial(k) * factorial(n - k)) # 原part_b函数可保留 def part_b(): print(1) rows = 13 for n in range(1, rows+1): line = [1] for k in range(1, n+1): line.append(binomial(n, k)) print(*line, sep=" ") part_b()
方法3:指定Numpy数组为64位整数
如果一定要用Numpy,把数组类型改成np.int64,它的最大值为9223372036854775807,能容纳到20!的计算:
修改后的binomial函数:
import numpy as np def binomial(n,k): # 指定数组类型为int64 factorial = np.ones([1,3], np.int64) for a in range(1,n+1): factorial[:,0] *=a for b in range(1,k+1): factorial[:,1] *=b for c in range(1,(n-k+1)): factorial[:,2] *=c solution = int(factorial[:,0]//(factorial[:,1]*factorial[:,2])) return solution # 原part_b函数不变 def part_b(): print(1) rows = 13 for n in range(1, rows+1): line = [1] for k in range(1, n+1): solution = binomial(n,k) line.append(solution) print(*line, sep=" ") part_b()
内容的提问来源于stack exchange,提问作者Maren
相关产品推荐
相关产品推荐

