This is due to floating point precision. Taking a look at the actual decimal representation of the floats without any rounding will make it clearer:
15.1%1
# 0.09999999999999964
16.1%1
# 0.10000000000000142
Note that just like python's range
, np.arange
does not include the end
in the created range, hence unless the floating point error results in a value greater than the step in the end
of the range, it will not be included. That is the case of the first float
, which has a decimal part lower than 0.1
.
The docs do suggest using np.linspace
when using a non-integer step, since the results can be inconsistent, precisely for the above reason.
Moreover it includes a endpoint
parameter, which allows you to do:
np.linspace(14.1,15.1, 11, endpoint=True)
# array([14.1, 14.2, 14.3, 14.4, 14.5, 14.6, 14.7, 14.8, 14.9, 15. , 15.1])
And, as @divakar suggests, to generalize you can set num
as:
start = 14.1
stop = 15.1
step = 0.1
num = 1+int((stop-start)/step)
np.linspace(start, stop, num, endpoint=True)
# array([14.1, 14.2, 14.3, 14.4, 14.5, 14.6, 14.7, 14.8, 14.9, 15. , 15.1])