np.int16 和 int16 matlab 之间的区别?

diffrence between np.int16 and int16 matlab?

我正在将 matlab 代码转换为 Python。在 matlab 中有一行将复数转换为 int16:

real = int16(real(-3.406578165491512e+04 + 9.054663292273188e+03i));
imag= int16(imag(-3.406578165491512e+04 + 9.054663292273188e+03i));  

real= -32768
imag=9055

在 python 我试过这个:

real = np.int16(round(np.real(-3.406578165491512e+04 + 9.054663292273188e+03j)))
imag = np.int16(round(np.imag(-3.406578165491512e+04 + 9.054663292273188e+03j)))

real= 31470
imag=9055

结果不同(我有许多其他值,例如 (1.815808483565253e+04 + 3.533772674703890e+04j) 有不同的答案!)你能帮我得到相同的答案吗?

MATLAB 输出在 intmin('int16') = -32768 (docs) 处饱和,即它可以表示为 int16 变量的最负值。

Python 与 int16 (docs) 具有相同的范围,但它没有在最负值处饱和,而是经历了下溢,环绕到范围的顶部

k = round(-3.406578165491512e+04) = -34066
k = k + (32768*2) = 31470

当输入仍然是浮点值时,您可以通过强制执行您的首选行为来解决这个问题,然后当输入在 -32768 to 32767 范围内时,您可以将其转换为 int16.

Wolfie 有所不同,这就是关于如何解决它的问题。如果您对裁剪没问题,那么您可以使用 iinfo to get the min and max values of an integer type (or hard-code it, if you know you won't be changing it from int16 ever) and then use clip 将浮动限制在这些范围内,然后再进行投射。

n = -3.406578165491512e+04

ii = np.iinfo(np.int16)
print(f"min = {ii.min}") # min = -32768
print(f"max = {ii.max}") # max = 32767

np.int16(np.clip(n, ii.min, ii.max))
# -32768

重要说明:这仅在浮点数大于 int 的大小时才可靠,因为它依赖于能够表示 ii.max完全像一个浮动。 See here for a discussion of when this is not true.

这是一个失败的例子

n = np.float64(1e100)

ii = np.iinfo(np.int64)
print(f"max: {ii.max}") # max = 9223372036854775807

clipped = np.clip(n, ii.min, ii.max)
print(f"clipped to: {int(clipped)}") # clipped to: 9223372036854775808
print(f"as int: {np.int64(clipped)}") # as int: -9223372036854775808

(这是因为ii.max不能表示为浮点数。9007199254740992之后,我们失去了1的精度位置,只能指定偶数,所以裁剪的边界变得不正确。)