I am converting a matlab code to Python. In matlab there is a line which converting the complex number to the int16:
real = int16(real(-3.406578165491512e+04 + 9.054663292273188e+03i));
imag= int16(imag(-3.406578165491512e+04 + 9.054663292273188e+03i));
real= -32768
imag=9055
In python I have tried this:
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
The results are different (I have had many other values such as (1.815808483565253e+04 + 3.533772674703890e+04j) with different answer!) would you please help me to get the same answer?
Wolfie gets at the difference, this is about how to solve it. If you're OK with clipping, then you can use 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 to constrain the float to be within those bounds before casting it.
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
IMPORTANT NOTE: This is only reliable if the size if your float is larger than the size of the int, because it relies upon being able to represent ii.max
exactly as a float. See here for a discussion of when this is not true.
Here's an example of that failing
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
(This happens because ii.max cannot be represented as a float. Past 9007199254740992, we lose the 1's place of precision and can only specify even integers, so the bounds of the clipping become incorrect.)