Resuelto: Desbordamiento encontrado en Double_Scalars en Python

Jay Shaw 21 junio 2023
  1. Causas del error desbordamiento encontrado en double_scalars en Python
  2. Formas de evitar el error desbordamiento encontrado en double_scalars
  3. Alguna otra advertencia de desbordamiento que surge en Python
  4. Conclusión
Resuelto: Desbordamiento encontrado en Double_Scalars en Python

Los escalares dobles definidos en el paquete de la biblioteca de Python Numpy son un valor de tipo de datos doble. Este tipo de datos se utiliza para calcular números de gran magnitud.

A menudo, la magnitud de estos números es tan grande que el programa se ejecuta en un estado de desbordamiento y muestra una advertencia de “desbordamiento encontrado en escalares dobles”. Este artículo explicará el desbordamiento en escalares dobles, una determinada situación que causa este problema y cómo se puede resolver.

Causas del error desbordamiento encontrado en double_scalars en Python

Los escalares dobles vienen con un rango más alto y más bajo. Los cálculos aritméticos con números más pequeños producen resultados normalmente, pero cuando estos números se elevan a potencias por encima de un determinado umbral, se produce el problema del desbordamiento que se produce en los dobles escalares.

Veamos un ejemplo para entenderlo.

Este programa muestra el rango de escalares dobles, muestra los cálculos en el borde del rango y luego el punto donde ocurre el error de desbordamiento; muestra la advertencia desbordamiento encontrado en double_scalars.

El programa importa el paquete de Python numpy y establece el manejo de errores en all='warn', lo que genera una advertencia durante el tiempo de ejecución por errores.

import numpy as np

np.seterr(all="warn")

Para encontrar el rango de un tipo de datos numpy, utilizaremos la rutina de tipo de datos finfo. Esta rutina, cuando se invoca, devuelve un límite de tipos de punto flotante como doble escalar dentro del sistema.

Encontrar el límite inferior de un escalar doble, es decir, su mínimo, requerirá una sintaxis como - np.finfo(np.double).min. En este programa, los valores mínimo y máximo se encuentran utilizando las subrutinas min y max.

print("Range of numpy double:", np.finfo(np.double).min, np.finfo(np.double).max)

Para encontrar los valores en el borde del rango, se crea una matriz numérica A de tipo de datos doble. Esta matriz tiene un solo elemento con el valor 143.

El valor del índice 0 se copia en una variable a para elevar este valor a la potencia de sí mismo de esta matriz. Luego, esta variable se eleva a la potencia de sí misma usando a**a.

A = np.array([143], dtype="double")
a = A[0]
print("At the border:", a ** a)

El programa se ejecuta correctamente hasta el código anterior, pero cuando se ejecuta una operación fuera del rango dado de escalares dobles, se produce un desbordamiento encontrado en escalares_dobles.

Se crea una nueva matriz, B, que almacena un valor mayor que el utilizado en la matriz anterior para reproducir este aviso.

Cuando este valor se eleva a la potencia de sí mismo, los programas muestran la advertencia desbordamiento encontrado en double_scalars.

import numpy as np

np.seterr(all="warn")
print("Range of numpy double:", np.finfo(np.double).min, np.finfo(np.double).max)
A = np.array([143], dtype="double")
a = A[0]
print("At the border:", a ** a)
B = np.array([144], dtype="double")
b = B[-1]
print("Blowing out of range:", b ** b)

Producción :

C:/Users/Win 10/PycharmProjects/overflow_longscalars/2.py:11: RuntimeWarning: overflow encountered in double_scalars
  print("Blowing out of range:", b ** b)
Range of numpy double: -1.7976931348623157e+308 1.7976931348623157e+308
At the border: 1.6332525972973913e+308
Blowing out of range: inf

Formas de evitar el error desbordamiento encontrado en double_scalars

Como se ve en el ejemplo anterior, cruzar el rango más alto de un tipo de datos puede resultar en un desbordamiento encontrado en double_scalars. La mejor manera de evitar este error es trabajar dentro del rango dado o aumentar la potencia de cálculo.

Pero hay algunos casos en los que el tipo de datos crea un cuello de botella. Aquí hay un programa que transmite la misma advertencia.

La primera matriz de tipo de datos float32 se desborda cuando el valor 143 se eleva a la potencia de sí mismo. Esto sucede porque float puede transportar hasta 8 bits de exponentes.

Por otro lado, el tipo de datos doble puede soportar el cálculo de hasta 11 bits de exponente, por lo que no entra en el desbordamiento y produce el resultado.

import numpy as np

np.seterr(all="warn")

A = np.array([143], dtype=np.float32)
a = A[-1]
print("Array with datatype float:", a ** a)
B = np.array([143], dtype=np.double)
b = B[-1]
print("Array with datatype double", b ** b)

Producción:

El programa se encuentra con un desbordamiento similar a los escalares dobles cuando un programa intenta ejecutar a**a y muestra inf en la salida, lo que significa que los resultados son infinitos.

Sin embargo, obtenemos el resultado deseado cuando se utilizan diferentes tipos de datos.

Array with datatype float: inf
Array with datatype double 1.6332525972973913e+308
C:/Users/Win 10/PycharmProjects/overflow_longscalars/5.py:7: RuntimeWarning: overflow encountered in float_scalars
  print("Array with datatype float:", a ** a)

Algunos cálculos usan infinito para expresar los resultados que están fuera de rango, lo que significa que el resultado es enorme.

El rango de números para tipos de datos como float64 va desde -1.79769313486e+308 a 1.79769313486e+308. Se observa que ir más grande o más pequeño provoca desbordamiento.

Por ejemplo, si el rango máximo - np.double(1.79769313486e+308) se multiplica por 1.1, se recibe la advertencia de tiempo de ejecución overflow found in double_scalars.

Hay que tener en cuenta que esto es solo un aviso y que sigue funcionando.

Sin embargo, debido a que el número sería demasiado grande, no puede devolver uno. En su lugar, proporciona inf.

Aunque algunos cálculos válidos usan infinito, algunos producen nan, que significa ningún número, como en el programa a continuación.

import numpy as np

var1 = np.inf - 10 ** 6
var2 = np.inf + 10 ** 6
var3 = np.inf / 10 ** 6
var4 = np.inf * 10 ** 6
var5 = np.inf * (-(10 ** 6))
var6 = 1 / np.inf
var7 = np.inf * np.inf
var8 = np.inf / np.inf
var9 = np.inf - np.inf

print(var1, var2, var3, var4, var5, var6, var7, var8, var9)

Producción :

inf inf inf inf -inf 0.0 inf nan nan

El programa anterior muestra todos los escenarios posibles donde se pueden encontrar infinito y nan.

A veces, un programa no entra en el estado de desbordamiento o muestra infinito o NaN, pero produce resultados que no solo son inexactos sino significativamente incorrectos.

En el siguiente ejemplo, se declara una matriz A del tipo de datos int64. Este tipo de datos almacena diferentes bits dependiendo de la máquina utilizada.

Cuando un valor almacenado dentro de esta variable se eleva a la potencia de sí mismo, el programa genera valores insignificantes en lugar de sufrir un desbordamiento o mostrar infinito.

Por ejemplo, un número entero positivo como 50, cuando se eleva a la potencia de sí mismo, debería producir un número entero positivo, pero cuando se ejecuta el siguiente código, el resultado es un valor negativo.

import numpy as np

np.seterr(all="warn")
A = np.array([50], dtype=np.int64)
a = A[-1]
print(a ** a)

Producción :

-6646187150092009472

Pero obtenemos el resultado apropiado cuando el mismo valor se almacena en un tipo de datos como doble o doblelargo.

import numpy as np

np.seterr(all="warn")
A = np.array([50], dtype=np.longdouble)
a = A[-1]
print(a ** a)

Producción :

8.881784197001252e+84

Nota: Debe tenerse en cuenta que la advertencia de tiempo de ejecución “desbordamiento encontrado en escalares_dobles” puede evadirse solo hasta que los números se desplacen a lo largo del rango del tipo de datos.

Aunque salir de ese rango no interrumpe el programa y crea un error, ignorar la advertencia “desbordamiento encontrado en double_scalars” puede tener el costo de generar resultados inestables.

Alguna otra advertencia de desbordamiento que surge en Python

Esta sección nos enseñará a detectar errores de desbordamiento que no sean escalares dobles. Hay principalmente otros dos desbordamientos que surgen a menudo.

  1. Desbordamiento encontrado en power

    Cuando se utiliza la subrutina numpy power para elevar un número a la potencia de sí mismo, y la resultante está fuera del rango, arroja el error overflow found in power.

    import numpy as np
    
    np.seterr(all="warn")
    print(np.power(143, 144, dtype=np.double))
    

    Producción:

    inf
    C:/Users/main.py:12: RuntimeWarning: overflow encountered in power
    print(np.power(143, 144, dtype=np.double))
    
  2. Desbordamiento encontrado en exp

    Este tipo de desbordamiento se encuentra durante las operaciones con exponentes. Elevar un número a la potencia de grandes exponentes da como resultado inf, mientras que dividirlo por esa cifra da como resultado un cero.

    import numpy as np
    
    print(1 * (1 + np.exp(1140)))
    print(1 / (1 + np.exp(1140)))
    

    Producción:

    inf
    0.0
    C:/Users/main.py:7: RuntimeWarning: overflow encountered in exp
    print(1*(1+np.exp(1140)))
    C:/Users/main.py:8: RuntimeWarning: overflow encountered in exp
    print(1/(1+np.exp(1140)))
    

Conclusión

Este artículo explica cómo evadir advertencias de tiempo de ejecución como “desbordamiento encontrado en double_scalars”, etc. Después de leer este artículo, el lector puede detectar errores de desbordamiento fácilmente.