You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免NumPy matmul溢出?为何int8转int16仍得错误值

问题代码与输出

import numpy as np

x1 = np.arange(0,63, dtype=np.int8).reshape(63,1)
x2 = np.arange(0,63, dtype=np.int8).reshape(1,63)
o = np.zeros((63,63), dtype=np.int16)
o = np.matmul(x1,x2)
print(o)

输出:

[[   0    0    0 ...    0    0    0]
 [   0    1    2 ...   60   61   62]
 [   0    2    4 ...  120  122  124]
 ...
 [   0   60  120 ...   16   76 -120]
 [   0   61  122 ...   76 -119  -58]
 [   0   62  124 ... -120  -58    4]]

问题描述

使用np.int8类型创建矩阵x1和x2,二者数值均在int8范围内。执行np.matmul运算后,结果超出int8范围,因此将结果存入int16类型变量,但仍得到错误值,请问这是为什么?


原因分析

numpy的矩阵乘法运算精度由输入数组的 dtype 决定,而非最终赋值的变量类型:

  • x1和x2都是int8类型,np.matmul会默认用int8精度执行乘法运算。int8的取值范围是-128~127,当两个int8数值相乘(比如62*62=3844),结果远超出范围,运算时直接发生溢出截断——数值会被对256取模后映射到int8区间,比如3844%256=4,这就是你看到最后一个元素是4的原因。
  • 你提前创建的int16变量o没有起到作用,因为o = np.matmul(x1,x2)是把已经溢出的int8结果直接赋值给o,此时只是把错误的int8数值转换为int16类型,无法恢复溢出前的正确值。

解决方法

方法1:运算前转换输入数组的 dtype

把x1和x2提前转成int16,让乘法在更高精度下执行:

import numpy as np

x1 = np.arange(0,63, dtype=np.int8).reshape(63,1).astype(np.int16)
x2 = np.arange(0,63, dtype=np.int8).reshape(1,63).astype(np.int16)
o = np.matmul(x1,x2)
print(o)

方法2:指定matmul的运算 dtype(numpy 1.20+支持)

直接在np.matmul中指定运算时使用的精度,无需转换输入数组:

import numpy as np

x1 = np.arange(0,63, dtype=np.int8).reshape(63,1)
x2 = np.arange(0,63, dtype=np.int8).reshape(1,63)
o = np.matmul(x1,x2, dtype=np.int16)
print(o)

内容的提问来源于stack exchange,提问作者Sristi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:20:28