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

numpy.arange生成数组时第7行元素超出预期的原因解析

np.arange生成数组超出预期范围的原因分析

问题重现

执行以下代码:

import numpy as np
for i in range(9):
    x = np.arange(i+0.8, i+1.3, 0.1)
    print(i, x)

得到输出:

0 [0.8 0.9 1.  1.1 1.2]
1 [1.8 1.9 2.  2.1 2.2]
2 [2.8 2.9 3.  3.1 3.2]
3 [3.8 3.9 4.  4.1 4.2]
4 [4.8 4.9 5.  5.1 5.2]
5 [5.8 5.9 6.  6.1 6.2]
6 [6.8 6.9 7.  7.1 7.2]
7 [7.8 7.9 8.  8.1 8.2 8.3]
8 [8.8 8.9 9.  9.1 9.2]

其中i=7时生成的数组包含了8.3,而按预期np.arange应该不包含终止值i+1.3=8.3。

原因解析

  1. 浮点数精度误差是核心问题
    np.arange的工作逻辑是:从起始值开始,不断累加步长,直到下一个值严格大于终止值时停止。但十进制的0.1无法用二进制浮点数精确表示,实际存储的是一个略大于0.1的近似值,多次累加后会产生误差累积。

  2. 为什么刚好在i=7时出现
    当i=7时,起始值为7.8,终止值为8.3:

  • 理论上最后一个元素应该是8.2,因为8.2+0.1=8.3等于终止值,不应被包含。
  • 但由于浮点数误差,前面累加得到的8.2实际存储为8.199999999999999,加上步长0.1的近似值后,结果是8.299999999999998——这个值略小于8.3的实际存储值(8.300000000000001),所以np.arange会把这个值当作合法元素加入数组,最终打印时显示为8.3。

其他循环中,误差累积的方向或幅度没触发这个边界条件,所以没有出现多元素的情况。

解决方案

  • 使用np.linspace替代:可以直接指定生成元素的数量,避免浮点数步长的误差问题,例如np.linspace(i+0.8, i+1.2, 5)(对应预期的5个元素)。
  • 给终止值减去极小epsilon:比如np.arange(i+0.8, i+1.3 - 1e-10, 0.1),确保累加后的结果不会误判为小于终止值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 20:44:58