Я хотел бы воспроизвести поведение C в Python, предположительно, используя numpy, но я столкнулся с этой проблемой:
>>> import numpy
>>> a = numpy.uint32(4294967295)
>>> type(a)
<class 'numpy.uint32'>
>>> a += 1
>>> a
4294967296
>>> type(a)
<class 'numpy.int64'>
В C с uint32 я бы получил 4294967295 + 1 = 0
Могу ли я заставить свой массив a оставаться массивом numpy.uint32, чтобы получить 0 в конце моего скрипта?
В связи с другим моим вопросом: Точно ли numpy воспроизводит все поведение C при обычных операциях?
В данном конкретном случае вы можете использовать: a = (a+1).astype(numpy.uint32).
Вы можете использовать a = np.uint32(a + 1)
Имеет ли значение добавление np.uint32(1)? Python 1 по умолчанию становится int64.
@hpaulj - Это сработало с предупреждением о переполнении.
Мне кажется, что такое поведение нарушает собственную документацию numpy. Скаляры-массивы Основное преимущество использования скаляров-массивов заключается в том, что они сохраняют тип массива (Python может не иметь подходящего типа скаляра, например, int16). Таким образом, использование скаляров-массивов обеспечивает идентичное поведение между массивами и скалярами, независимо от того, находится ли значение внутри массива или нет. Обратите внимание, что arr = numpy.array([numpy.uint32(4294967295)]) тогда arr += 1 остается uint32.
@tdelaney, см. мой дополнительный вопрос: stackoverflow.com/questions/78186300/….
Возможно, вам будет интересно узнать, что недавно выпущенный NumPy 2.0 меняет правила продвижения типов, так что np.uint32 + int теперь создает uint32. См. numpy.org/doc/stable/… и редактирование моего ответа.






Здесь вы не используете массив, и это важно, потому что NumPy не обязательно имеет одинаковое поведение между скаляром и массивом размером один.
Например, операции над массивом на месте никогда не изменяют тип массива.
Пример:
import numpy
a = numpy.array([4294967295], dtype='uint32')
a += 1
print(a)
print(a.dtype)
Выход:
[0]
uint32
Обновлено: NumPy 2.0 уже вышел, и одним из изменений является сохранение скалярного типа.
>>> import numpy as np
>>> a = np.uint32(4294967295)
>>> a += 1
<stdin>:1: RuntimeWarning: overflow encountered in scalar add
>>> a
np.uint32(0)
>>> type(a)
<class 'numpy.uint32'>
Поэтому одной из альтернатив является использование NumPy 2.0 или выше.
Побитовое И с 0xFFFF_FFFF даст 0.