Reputation: 1761
What is the reason those two divisions give different results? I am very confused because with some numbers it gives the same results and with some it doesn't.
>>> import numpy as np
>>> a, b = np.array([844]), np.array([8186])
>>> a.dtype, b.dtype
(dtype('int32'), dtype('int32'))
>>> np.true_divide(a, b, dtype=np.float32)
array([ 0.10310286], dtype=float32)
>>> np.true_divide(a, b, dtype=np.float64)
array([-12.66666667]) # different result
>>> np.true_divide(a, b, dtype=np.float32).astype(np.float64)
array([ 0.10310286])
>>> a, b = np.array([1]), np.array([2])
>>> np.true_divide(a, b, dtype=np.float32)
array([ 0.5], dtype=float32)
>>> np.true_divide(a, b, dtype=np.float64)
array([ 0.5]) # same results
Tested on windows x64, python 3.5 and 3.6 x64, numpy 1.13.1.
EDIT: This was a numpy bug which has since been fixed (https://github.com/numpy/numpy/pull/9469).
Upvotes: 7
Views: 1869
Reputation: 23647
This is a bug in numpy. Although this was supposedly fixed in 2015 it looks like it is still causing problems.
When resolving the type signature fails because of the forced cast, true_divide
casts the input to int8
:
>>> np.int8(844) / np.int8(8186)
-12.666667
>>> np.true_divide(844, 8186, dtype=np.float64)
-12.666666666666666
You get the correct result only for numbers between -128 and 127 because that is the range available in int8
.
As a workaround you can specify the complete signature instead of only the return type:
>>> np.true_divide(844, 8186, signature='ii->d') # int32, int32 -> float64
0.10310285853896897
>>> np.true_divide(844, 8186, signature=(np.int32, np.int32, np.float64))
0.10310285853896897
Upvotes: 1