matlab - ¿Cómo lidiar con el desbordamiento y el desbordamiento?
math rounding (1)
Soy nuevo en Matlab y trato de descubrir cómo puedo lidiar con la aritmética de desbordamiento y subflujo cuando la respuesta está realmente dentro del rango.
Por ejemplo:
x = 2e+160
x = x*x (which returns inf, an overflow)
x = sqrt(x) (which is in the range)
Cualquier ayuda es apreciada.
No soy un usuario de Matlab, así que tenlo en cuenta.
El principal problema detrás de esto es primero detectar los desbordamientos / desbordamientos
Eso a veces es difícil porque también aparecen en otros casos cuando el cálculo no devuelve
zero
o
inf
.
Por ejemplo, durante la integración numérica, los desbordamientos / desbordamientos pueden causar que el resultado sea incorrecto pero que aún sea un número distinto de cero.
En mi experiencia, considero que es útil observar los números en su representación hexadecimal (a menos que sus cálculos HW / SW utilicen internamente una base decádica para las variables, lo cual es raro porque la mayoría de los HW / SW son binarios). Entonces vea el número en forma hexadecimal y detecte patrones como:
??????????.????FFFFFFFFFFF?? hex
cuando observa la parte fraccionaria y detecta que hay muchos
FFFFF
presentes cerca de los dígitos más bajos, entonces es
muy probable
que su número se desborde o esté muy cerca de ese punto.
El número de ceros o lo que sea al final generalmente disminuye con cada iteración saturando a:
??????????.????FFFFFFFFFFF hex
Los desbordamientos están saturados de manera similar pero en el otro lado así:
FFFFFFFFFFF.FFFFFF?????? hex
Para algunos algoritmos es más preciso redondear hacia arriba / hacia abajo dichos números antes de la próxima iteración, pero siempre debe verificar si ese es el caso en algún ejemplo bien conocido de cálculos antes de aplicar sobre incógnitas ... Mire aquí:
- divisor de coma flotante
Es un buen ejemplo de algoritmo que utiliza esta técnica
Otra forma de detectar desbordamientos / subflujos es la predicción de la magnitud del número de resultado. Por ejemplo
-
*
suma los exponentes juntos -
/
restar los exponentes -
sqrt
reduce a la mitad el exponente -
+
,-
puede resultar en+1/-1
del exponente más grande
Entonces, si se trata de exponentes grandes / pequeños, sabe qué operaciones podrían conducir a problemas desbordados.
Además de eso, pueden ocurrir desbordamientos cuando la precisión de los resultados no se ajusta a la mantisa. Por lo tanto, debe tener cuidado con las operaciones que aumentan los bits utilizados del resultado, como:
-
a*b
suma de bits usados ena
,b
-
+,-
bit usado máximo de (a, b) - bit usado mínimo de (a, b) -
/
agrega algunos bits para contener las fracciones ...
La operación
+,-
es la peor, por ejemplo, si agrega
2^100 + 2^-100
entonces el resultado necesita 200 bits de mantisa, mientras que los operandos en sí tienen solo 1 bit de mantisa.
Qué hacer si se detecta desbordamiento / subflujo:
-
cambiar la ecuación
Como se mencionó, puede cambiar al
log
que puede manejar rangos más grandes con facilidad, pero tiene otros problemas. También, por lo general, un ligero cambio en el algoritmo puede conducir a resultados escalados por diferentes factores, pero con los resultados secundarios aún en un rango seguro, por lo que solo necesita el resultado final para volver a escalar a un rango peligroso. Al cambiar las ecuaciones, siempre debe tener en cuenta la precisión y la validez del resultado. -
usar un tipo de datos variable más grande
Si recuerdo correctamente, Matlab tiene números de precisión arbitrarios, así que úselos si es necesario. También puede usar variables
float/double
estándar y almacenar el valor en más variables, como aquí:- Incremento de la precisión de integración numérica
-
deja de iterar
Por ejemplo, algunos algoritmos usan series como:
1/1! + 1/2! + 1/3! + ... + 1/n!
en algunos casos, si detecta que golpeó el subresultado desbordado / subdesbordado cuando detiene la iteración, aún tiene un resultado relativamente preciso del cálculo. No olvide no incluir subresultados desbordados en el resultado final.