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).
In Python 3. x, slash operator ("/") does true division for all types including integers, and therefore, e.g. 3/2==1.5.
Java does integer division, which basically is the same as regular real division, but you throw away the remainder (or fraction). Thus, 7 / 3 is 2 with a remainder of 1. Throw away the remainder, and the result is 2. Integer division can come in very handy.
The division function in Python has two variations: Float division: gives a decimal answer. Integer division: gives the answer in whole numbers (the division result is rounded to the nearest whole number).
Use the floor division operator // to return an integer from integer division, e.g. result_1 = 30 // 6 . The floor division operator will always return an integer and is like using mathematical division with the floor() function applied to the result.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With