Question about numpy.arange()

Hello,
Is "b" an expected value? I am suspecting another floating point arithmetic issue.
I[1]: a = np.arange(1.6, 1.8, 0.1, dtype='float32')
I[2]: a O[2]: array([ 1.60000002, 1.70000005], dtype=float32)
I[3]: b = np.arange(1.7, 1.8, 0.1, dtype='float32')
I[4]: b O[4]: array([ 1.70000005, 1.79999995], dtype=float32)
A bit conflicting with the np.arange docstring:
"* Values are generated within the half-open interval ``[start, stop)`` (in other words, the interval including `start` but excluding `stop`). * "
Thanks.

On 1 May 2010 16:36, Gökhan Sever gokhansever@gmail.com wrote:
Hello,
Is "b" an expected value? I am suspecting another floating point arithmetic issue.
I[1]: a = np.arange(1.6, 1.8, 0.1, dtype='float32')
I[2]: a O[2]: array([ 1.60000002, 1.70000005], dtype=float32)
I[3]: b = np.arange(1.7, 1.8, 0.1, dtype='float32')
I[4]: b O[4]: array([ 1.70000005, 1.79999995], dtype=float32)
A bit conflicting with the np.arange docstring:
" Values are generated within the half-open interval ``[start, stop)`` (in other words, the interval including `start` but excluding `stop`). "
This is a floating-point issue; since 1.79999995 does not actually equal 1.8, it is included. This arises because 0.1, 1.7, and 1.8 cannot be exactly represented in floating-point.
A good rule to avoid being annoyed by this is: only use arange for integers. Use linspace if you want floating-point.
Anne
Thanks.
-- Gökhan
NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Sat, May 1, 2010 at 1:36 PM, Gökhan Sever gokhansever@gmail.com wrote:
Hello,
Is "b" an expected value? I am suspecting another floating point arithmetic issue.
I[1]: a = np.arange(1.6, 1.8, 0.1, dtype='float32')
I[2]: a O[2]: array([ 1.60000002, 1.70000005], dtype=float32)
I[3]: b = np.arange(1.7, 1.8, 0.1, dtype='float32')
I[4]: b O[4]: array([ 1.70000005, 1.79999995], dtype=float32)
A bit conflicting with the np.arange docstring:
" Values are generated within the half-open interval ``[start, stop)`` (in other words, the interval including `start` but excluding `stop`). "
Try np.linspace(). It works better with floats:
np.linspace(1.7, 1.8, 2)
array([ 1.7, 1.8])

Gökhan Sever wrote:
Hello,
Is "b" an expected value? I am suspecting another floating point arithmetic issue.
Exactly. You'll see the same type of problem with float64, too:
In [17]: z = np.arange(1.7, 1.8, 0.1)
In [18]: z Out[18]: array([ 1.7, 1.8])
In [19]: z[1] == 1.8 Out[19]: True
In [20]: z[1] - 1 Out[20]: 0.80000000000000004
Fun stuff, eh?
To avoid problems like this, I generally use linspace instead of arange.
Warren
I[1]: a = np.arange(1.6, 1.8, 0.1, dtype='float32')
I[2]: a O[2]: array([ 1.60000002, 1.70000005], dtype=float32)
I[3]: b = np.arange(1.7, 1.8, 0.1, dtype='float32')
I[4]: b O[4]: array([ 1.70000005, 1.79999995], dtype=float32)
A bit conflicting with the np.arange docstring:
"/ Values are generated within the half-open interval ``[start, stop)`` (in other words, the interval including `start` but excluding `stop`). /"
Thanks.
-- Gökhan
NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Sat, May 1, 2010 at 15:36, Gökhan Sever gokhansever@gmail.com wrote:
Hello,
Is "b" an expected value? I am suspecting another floating point arithmetic issue.
I[1]: a = np.arange(1.6, 1.8, 0.1, dtype='float32')
I[2]: a O[2]: array([ 1.60000002, 1.70000005], dtype=float32)
I[3]: b = np.arange(1.7, 1.8, 0.1, dtype='float32')
I[4]: b O[4]: array([ 1.70000005, 1.79999995], dtype=float32)
A bit conflicting with the np.arange docstring:
" Values are generated within the half-open interval ``[start, stop)`` (in other words, the interval including `start` but excluding `stop`). "
Not at all. 1.79999995 < 1.8 . However, also note this warning in the arange() docs:
""" For floating point arguments, the length of the result is ``ceil((stop - start)/step)``. Because of floating point overflow, this rule may result in the last element of `out` being greater than `stop`. """
You probably want linspace() instead.

On Sat, May 1, 2010 at 3:36 PM, Gökhan Sever gokhansever@gmail.com wrote:
Hello,
Is "b" an expected value? I am suspecting another floating point arithmetic issue.
I[1]: a = np.arange(1.6, 1.8, 0.1, dtype='float32')
I[2]: a O[2]: array([ 1.60000002, 1.70000005], dtype=float32)
I[3]: b = np.arange(1.7, 1.8, 0.1, dtype='float32')
I[4]: b O[4]: array([ 1.70000005, 1.79999995], dtype=float32)
A bit conflicting with the np.arange docstring:
"* Values are generated within the half-open interval ``[start, stop)`` (in other words, the interval including `start` but excluding `stop`). *"
Thanks.
-- Gökhan
Fair enough explanations to use np.linspace instead. What was confusing me above while a[1] and b[0] shows 1.70000005 only "b" steps up to 1.79999995 which "a" can't.
The following is another surprise output:
I[5]: c = np.arange(0.4, 0.5, 0.1, dtype='float32')
I[6]: c O[6]: array([ 0.40000001], dtype=float32)
Anyways, a Slashdotter might have seen me asking these questions. I will go read What Every Programmer Should Know About Floating-Point Arithmetichttp://developers.slashdot.org/story/10/05/02/1427214/What-Every-Programmer-Should-Know-About-Floating-Point-Arithmeticarticle.

On 5/2/2010 1:51 PM, Gökhan Sever wrote:
The following is another surprise output:
I[5]: c = np.arange(0.4, 0.5, 0.1, dtype='float32') [6]: c O[6]: array([ 0.40000001], dtype=float32)
a = np.array([0.4,0.5,0.1], dtype='float32') a[0]
0.40000001
(a[1]-a[0])/a[2]
0.99999994
np.ceil((a[1]-a[0])/a[2])
1.0
The docstring states:
For floating point arguments, the length of the result is ``ceil((stop - start)/step)``.
hth, Alan Isaac
participants (6)
-
Alan G Isaac
-
Anne Archibald
-
Gökhan Sever
-
Keith Goodman
-
Robert Kern
-
Warren Weckesser