Estoy convirtiendo un código de Matlab a Python. En matlab hay una línea que convierte el número complejo a int16:
real = int16(real(-3.406578165491512e+04 + 9.054663292273188e+03i)); imag= int16(imag(-3.406578165491512e+04 + 9.054663292273188e+03i)); real= -32768 imag=9055En python he probado esto:
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=9055Los resultados son diferentes (¡he tenido muchos otros valores como (1.815808483565253e+04 + 3.533772674703890e+04j) con una respuesta diferente!) ¿Podría ayudarme a obtener la misma respuesta?
La salida de MATLAB se ha saturado en intmin('int16') = -32768 ( docs ), es decir, el valor más negativo que puede representar como una variable int16 .
Python tiene el mismo rango para int16 ( docs ), pero en lugar de saturarse en el valor más negativo, ha experimentado un desbordamiento, llegando a la parte superior del rango.
k = round(-3.406578165491512e+04) = -34066 k = k + (32768*2) = 31470 Puede evitar esto aplicando cualquiera de estos que sea su comportamiento preferido cuando las entradas aún son valores de coma flotante, y luego, cuando la entrada está dentro del rango -32768 to 32767 , puede convertirla en int16 .
Wolfie entiende la diferencia, se trata de cómo resolverlo. Si está de acuerdo con el recorte, puede usar iinfo para obtener los valores mínimo y máximo de un tipo entero (o codificarlo, si sabe que no lo cambiará de int16 nunca) y luego use clip para restrinja el flotador para que esté dentro de esos límites antes de lanzarlo.
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 NOTA IMPORTANTE : Esto solo es confiable si el tamaño de su flotador es mayor que el tamaño del int, porque se basa en poder representar ii.max exactamente como un flotador. Ver aquí para una discusión de cuando esto no es cierto .
Aquí hay un ejemplo de esa falla
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(Esto sucede porque ii.max no se puede representar como un flotante. Pasado 9007199254740992, perdemos el lugar de precisión del 1 y solo podemos especificar números pares, por lo que los límites del recorte se vuelven incorrectos).