Skip to content
scipython.com

Q6.1.11The dtypes of scalars and arrays

The dtype np.uint8 represents an unsigned integer in 8 bits. Its value may therefore be in the range \(0 - 255\). Explain the following behaviour:

In [x]: x = np.uint8(250)
In [x]: x * 2
Out[x]: 500

In [x]: x = np.array([250,], dtype=np.uint8)
In [x]: x * 2
Out[x]: array([244], dtype=uint8)
Show solution

In the first case, a single object is created of the requested dtype and multiplied by a scalar (regular Python int). Python "upcasts" to return the result in dtype that can hold it:

In [x]: x = np.uint8(250)
In [x]: type(x * 2)
Out[x]: numpy.int64

However, a ndarray, because it has a fixed byte-size, cannot be upcast in the same way: its own dtype takes precedence over that of the scalar multiplying it and so the multiplication is carried out modulo 256.

Compare this with the result of multiplying two scalars with the same dtype:

In [x]: np.uint8(250) * np.uint8(2)
Out[x]: 244             # (of type np.uint8)

(You may also see a warning: RuntimeWarning: overflow encountered in ubyte_scalars.)