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.)