Search code examples
pythonnumpydot-product

Why does numpy.dot give incorrect results?


This code:

a = np.array([10], dtype=np.int8)
b = np.array([2],  dtype=np.int8)
print(np.dot(a, b))

a = np.array([10], dtype=np.int8)
b = np.array([5],  dtype=np.int8)
print(np.dot(a, b))

a = np.array([10], dtype=np.int8)
b = np.array([20], dtype=np.int8)
print(np.dot(a, b))

produces the following output:

20
50
-56

It appears that np.dot will attempt to return the result in the same data type object even if it can't fit. Surely this is a bug? Why doesn't it throw an exception?


Solution

  • This is true for multiplication and addition.

    In [89]: np.array([128], 'int8')*2
    Out[89]: array([0], dtype=int8)
    
    In [90]: np.array([127], 'int8')*2
    Out[90]: array([-2], dtype=int8)        # same int8 dtype
    

    But if I work with an element of the array, a np.int8 object, the result is promoted.

    In [91]: np.array([127], 'int8')[0]*2
    Out[91]: 254    
    In [92]: type(_)
    Out[92]: numpy.int32
    

    I think, though can't offhand produce, there are cases where this kind of thing raises an error.

    This has been discussed in other SO, for multiplication, if not for np.dot.

    This is a overflow question for 'uint8' dtypes, and github issues link:

    Allow overflow for numpy types

    https://github.com/numpy/numpy/issues/8987 "BUG: Integer overflow warning applies to scalars but not arrays"