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

Lex*_*exi 4 python matlab numpy type-conversion complex-numbers

我正在将 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
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

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

Wol*_*fie 6

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

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

k = round(-3.406578165491512e+04) = -34066
k = k + (32768*2) = 31470
Run Code Online (Sandbox Code Playgroud)

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


Kai*_*aia 5

Wolfie 明白了其中的区别,这是关于如何解决它的问题。如果你对裁剪没问题,那么你可以使用iinfo获取整数类型的最小值和最大值(或者对其进行硬编码,如果你知道你不会从 int16 更改它),然后使用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
Run Code Online (Sandbox Code Playgroud)

重要提示:只有当浮点数的大小大于 int 的大小时,这才是可靠的,因为它依赖于能够ii.max精确地表示为浮点数。请参阅此处讨论何时这不是真的

这是一个失败的例子

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
Run Code Online (Sandbox Code Playgroud)

(发生这种情况是因为 ii.max 无法表示为浮点数。过去 9007199254740992,我们失去了 1 的精度位置,只能指定偶数整数,因此裁剪的边界变得不正确。)