Difference between revisions of "Numpy surprises"

From Tech
Jump to navigationJump to search
(Created page with "New in numpy version 2: numpy int types aren't promoted to bigger types. >>> np.uint8(1) + 255 <python-input-21>:1: RuntimeWarning: overflow encountered in scalar add...")
 
 
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
New in numpy version 2: numpy int types aren't promoted to bigger types.
+
New in numpy version 2: numpy int types aren't promoted to bigger types in operations that involve a python int:
>>> np.uint8(1) + 255
+
>>> np.__version__
 
'2.2.4'
<python-input-21>:1: RuntimeWarning: overflow encountered in scalar add
 
  +
#
np.uint8(0)
 
  +
np.uint8(1) + 255
 
<python-input-21>:1: RuntimeWarning: overflow encountered in scalar add
  +
np.uint8(0)
  +
#
  +
# When the value of the int is bigger than would fit in the numpy type, an error is thrown:
  +
np.uint8(0)+256
  +
Traceback (most recent call last):
  +
File "<python-input-29>", line 1, in <module>
 
np.uint8(0)+256
  +
17:13, 11 December 2025 (CET)17:13, 11 December 2025 (CET)~^[[User:Joosteto|Joosteto]] ([[User talk:Joosteto|talk]])
  +
OverflowError: Python integer 256 out of bounds for uint8
  +
  +
   
>>> np.__version__
 
'2.2.4'
 
   
   
 
The old numpy 1.24 used to promote numpy int types to 64-bit:
 
The old numpy 1.24 used to promote numpy int types to 64-bit:
   
 
np.__version__
>>> type(np.uint8(1) + 1)
 
 
'1.24.2'
<class 'numpy.int64'>
 
  +
#
>>> np.__version__
 
 
type(np.uint8(1) + 1)
'1.24.2'
 
 
<class 'numpy.int64'>
  +
#or to bigger types, if needed
  +
type(np.uint8(1)+2**63)
  +
<class 'numpy.ulonglong'>
  +
  +
  +
  +
Also funny: the old 1.24 numpy 'promoted' the uint64 type to float when confronted with python int:
  +
  +
np.uint64(1)+1
  +
2.0
  +
type(np.uint64(1)+1)
  +
<class 'numpy.float64'>
  +
#
  +
#But... uin32 isn't promoted to float, but to... int64(!)
  +
type(np.uint32(1)+1)
  +
<class 'numpy.int64'>
  +
#
  +
# Same as uint8:
  +
type(np.uint8(1)+1)
  +
<class 'numpy.int64'>
  +
#
  +
# However, the signed versions, numpy.int64, numpy.int32 are just always converted to numpy.int64:
  +
type(np.int32(1)+1)
  +
<class 'numpy.int64'>
  +
#
 
np.__version__
  +
'1.24.2'
  +
  +
  +
This is all improved a lot in numpy 2:
  +
  +
type(np.uint64(1)+1)
  +
<class 'numpy.uint64'>
  +
#
  +
type(np.uint32(1)+1)
  +
<class 'numpy.uint32'>
  +
#
  +
type(np.int32(1)+1)
  +
<class 'numpy.int32'>
  +
#
  +
np.__version__
  +
'2.2.4'
  +
  +
And without warning/exception:
  +
  +
2**np.int8(8)
  +
np.int8(0)
  +
#
  +
np.int8(2)**8
  +
np.int8(0)
  +
#
  +
np.__version__
  +
'2.2.4'

Latest revision as of 09:54, 16 December 2025

New in numpy version 2: numpy int types aren't promoted to bigger types in operations that involve a python int:

>>> np.__version__
'2.2.4'
#
np.uint8(1) + 255
<python-input-21>:1: RuntimeWarning: overflow encountered in scalar add
np.uint8(0)
#
# When the value of the int is bigger than would fit in the numpy type, an error is thrown:
np.uint8(0)+256
Traceback (most recent call last):
  File "<python-input-29>", line 1, in <module>
    np.uint8(0)+256
    17:13, 11 December 2025 (CET)17:13, 11 December 2025 (CET)~^Joosteto (talk)
OverflowError: Python integer 256 out of bounds for uint8



The old numpy 1.24 used to promote numpy int types to 64-bit:

np.__version__
'1.24.2'
#
type(np.uint8(1) + 1)
<class 'numpy.int64'>
#or to bigger types, if needed
type(np.uint8(1)+2**63)
<class 'numpy.ulonglong'>


Also funny: the old 1.24 numpy 'promoted' the uint64 type to float when confronted with python int:

np.uint64(1)+1
2.0
type(np.uint64(1)+1)
<class 'numpy.float64'>
#
#But... uin32 isn't promoted to float, but to... int64(!)
type(np.uint32(1)+1)
<class 'numpy.int64'>
#
# Same as uint8:
type(np.uint8(1)+1)
<class 'numpy.int64'>
#
# However, the signed versions, numpy.int64, numpy.int32 are just always converted to numpy.int64:
type(np.int32(1)+1)
<class 'numpy.int64'>
#
np.__version__
'1.24.2'


This is all improved a lot in numpy 2:

type(np.uint64(1)+1)
<class 'numpy.uint64'>
#
type(np.uint32(1)+1)
<class 'numpy.uint32'>
#
type(np.int32(1)+1)
<class 'numpy.int32'>
#
np.__version__
'2.2.4'

And without warning/exception:

2**np.int8(8)
np.int8(0)
#
np.int8(2)**8
np.int8(0)
#
np.__version__
'2.2.4'