为何np.arange(0.6, 0.68, 0.01)会包含0.68?
关于numpy.arange浮点数边界的疑问与解释
测试代码与现象
>>> import numpy as np >>> np.arange(0.6, 0.68, 0.01) array([0.6 , 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68]) >>> np.arange(0.6, 0.69, 0.01) array([0.6 , 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68]) >>> np.arange(0.6, 0.70, 0.01) array([0.6 , 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69])
问题
为何np.arange(0.6, 0.68, 0.01)会包含数值0.68?我猜测这可能是数值精度问题,但不清楚具体原因。
解释
这确实是浮点数精度误差导致的问题。计算机采用二进制存储浮点数,像0.6、0.01这类十进制小数无法被二进制精确表示,存储时会带有微小的偏差。
以np.arange(0.6, 0.68, 0.01)为例:
- 理论上累加8次0.01后得到0.68,刚好等于终止值,按规则不应被包含。但实际计算中,每次累加的"0.01"是一个近似的二进制浮点数,累加8次后得到的结果略小于十进制的0.68。
- numpy的
arange逻辑是判断当前值是否小于终止值,这个略小的数值会被判定为符合条件,因此被加入数组。
再看np.arange(0.6, 0.69, 0.01):
- 累加9次近似0.01后得到的结果会略大于十进制的0.69,触发终止条件,所以数组最后只到0.68。
如果要避免这类边界问题,建议:
- 使用
np.linspace生成固定数量的等间隔数组,能更精准控制边界; - 对
arange的终止值做微小调整,比如用0.68 - 1e-10替代原终止值,抵消精度误差的影响。
内容的提问来源于stack exchange,提问作者jhhuang
相关产品推荐
相关产品推荐

