简体   繁体   English

在向uint8添加int时奇怪的类型转换?

[英]Strange typecasting when adding int to uint8?

I am somewhat confused by the way python/numpy work when typecasting unsigned integers. 在对类型无符号整数进行类型转换时,我对python / numpy的工作方式感到有些困惑。

Example: 例:

import numpy as np
x = np.array([255], dtype=np.uint8)
y = x + 1

This gives the result: 这给出了结果:

In[0]: y
Out[0]: array([0], dtype=uint8)

I understand that uint8 cannot store an integer with a larger value than 255 so it cycles back to zero. 我知道uint8不能存储一个大于255的整数,所以它循环回零。 I kind of expected this. 我有点期待这个。

Now I try: 现在我尝试:

z = x + 256

Which gives: 这使:

In[1]: z
Out[1]: array([511], dtype=uint16)

So in this case the type has changed to one with more bytes to hold the larger number, but only when the integer being added would itself not fit into the smaller type. 因此,在这种情况下,类型已更改为具有更多字节的类型以保存更大的数字,但仅当添加的整数本身不适合较小的类型时。 (Interestingly x + 255 does not give a uint16 result) (有趣的是,x + 255不会给出uint16结果)

This strikes me as somewhat odd behaviour. 这让我觉得有些奇怪的行为。 Is there any logic behind it? 它背后有什么逻辑吗? I would have thought a more consistent thing to do is to have the type change to uint16 in the first example case too. 我认为更一致的事情是在第一个示例案例中将类型更改为uint16。

This behaviour seems to stem from an understandable desire to keep array casting to an absolute minimum. 这种行为似乎源于将数组转换保持在绝对最小值的可理解的愿望。

Consider 考虑

z = np.uint8(255)
z + 1
# 256
type(z+1)
# numpy.int64

where the literal 1 has type int . 文字1类型为int It seems in that case both operands are cast to np.int64. 在这种情况下,似乎两个操作数都被强制转换为np.int64。 But this has nothing to do with the result! 但这与结果无关!

zz = np.uint8(1)
type(zz + 1)
# numpy.int64

The casting is however different if we use an array instead of a simple integer. 然而,如果我们使用数组而不是简单的整数,则转换是不同的。

x = np.array([255], dtype=np.uint8)
x + 1
# array([0], dtype=uint8)

Seems to me this is probably the case as it would be a large computational effort to cast an entire array from one type to another, so this is only done if it knows 100% sure this will be necessary before looking at all the array elements, ie only if the other operand itself does not fit in the current type. 在我看来这可能就是这种情况,因为将整个数组从一种类型转换为另一种类型需要大量的计算工作,所以只有在它确定100%确定查看所有数组元素之前这是必要的时候才会这样做,即仅当另一个操作数本身不适合当前类型时。 In fact, even if we take 事实上,即使我们采取

b = np.int16(1)
x+b
# array([0], dtype=uint8)

so it actually casts the right hand operand into a smaller type, all to save the array's type. 所以它实际上将右手操作数转换为较小的类型,所有这些都是为了保存数组的类型。 On the other hand, when adding two np.arrays, the type conversion is always made to the larger type. 另一方面,当添加两个np.array时,类型转换总是进行更大的类型。

Long story short: - simple integer addition always casts to the larger type of the operands - addition of a numpy array and an integer casts to the type of the array if this is sufficient to represent the integer, else to the type of the integer - addition of two numpy arrays casts to the larger type of the operands (as with two integer) 简而言之: - 简单的整数加法总是强制转换为更大类型的操作数 - 如果这足以表示整数,则添加一个numpy数组和一个整数强制转换为数组的类型,否则为整数的类型 - 添加两个numpy数组转换为更大类型的操作数(与两个整数一样)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM