Ответ 1
Это сознательное дизайнерское решение авторов numpy
. При выборе результирующего типа учитываются только типы операндов, а не их фактические значения. И для операции, которую вы выполняете, существует риск получить результат вне допустимого диапазона, например. если вы вычтите очень большое число uint64
, результат не будет соответствовать int64
. Таким образом, безопасный выбор преобразуется в float64
, что, безусловно, будет соответствовать результату (возможно, с уменьшенной точностью).
Сравните с примером x = np.int32(2) - np.uint32(1)
. Это всегда можно безопасно представить как int64
, поэтому выбран этот тип. То же самое верно для x = np.int64(2) - np.uint32(1)
. Это также даст int64
.
Альтернативой будет следовать, например, правила c, которые будут отбрасывать все на uint64
. Но это может, конечно, привести к очень странным результатам с превышением/недостатками.
Если вы хотите заранее знать, какой тип вы закончите, просмотрите np.result_type()
, np.can_cast()
и np.promote_types()
. Чтение об этом в документах также может помочь вам понять проблему немного лучше.