Solved: Overflow Encountered in Double_Scalars in Python

Solved: Overflow Encountered in Double_Scalars in Python

  1. Causes of overflow encountered in double_scalars Error in Python
  2. Ways to Avoid the Error overflow encountered in double_scalars
  3. Some Other Overflow Warning That Arises in Python
  4. Conclusion

Double scalars defined under Python library package Numpy is a value of data type double. This data type is used in calculating numbers of great magnitude.

Often, the magnitude of these numbers gets so large that the program runs into a state of overflow and displays a warning overflow encountered in double_scalars. This article will explain overflow in double scalars, a certain situation that causes this problem, and how it can be solved.

Causes of overflow encountered in double_scalars Error in Python

The double scalars come with a higher and lower range. Arithmetic calculations with smaller numbers produce results normally, but when these numbers are raised to powers over a certain threshold, the problem of overflow encountered in double_scalars occurs.

Let’s look at an example to understand it.

This program displays the range of double scalars, displays calculations at the border of the range, and then the point where the overflow error occurs; it displays the warning overflow encountered in double_scalars.

The program imports Python package numpy and sets error handling to all='warn', which raises a warning during runtime for errors.

import numpy as np

np.seterr(all='warn')

To find the range of a numpy data type, we will use the data type routine finfo. This routine, when invoked, returns a limit of floating point types like double scalar inside the system.

Finding the lower limit of a double scalar, i.e., its minimum, will require a syntax like - np.finfo(np.double).min. In this program, the minimum and maximum values are found using the min and max subroutines.

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

To find the values at the border of the range, a numpy array A of data type double is created. This array has a single element with the value 143.

The 0th index value is copied to a variable a to raise this value to the power of itself from this array. This variable is then raised to the power of itself using a**a.

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

The program runs correctly until the above code, but when an operation is executed outside the given range of double scalars, overflow encountered in double_scalars occurs.

A new array, B, is created that stores a greater value than the one used in the previous array to reproduce this warning.

When this value is raised to the power of itself, programs display the warning overflow encountered in 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)

Output:

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

Ways to Avoid the Error overflow encountered in double_scalars

As seen in the above example, crossing the highest range of a data type can result in overflow encountered in double_scalars. The best way to avoid this error is to work within the given range or increase the computational power.

But there are some cases where the data type creates a bottleneck. Here is a program that conveys the same warning.

The first array of datatype float32 overflows when the value 143 is raised to the power of itself. This happens because float can carry up to 8 bits of exponents.

On the other hand, datatype double can withstand calculation up to 11 exponent bits, which is why it does not get into the overflow and produces the result.

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)

Output:

The program runs into an overflow similar to the double scalars when a program tries to execute a**a and displays inf at the output, which means the results are infinite.

Though, we get the desired result when different data types are used.

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)

Some calculations use infinity to express the results that are out of range, which means that the result is huge.

The range of numbers for data type like float64 holds from -1.79769313486e+308 to 1.79769313486e+308. It is observed that going larger or smaller causes overflow.

For instance, if the maximum range - np.double(1.79769313486e+308) is multiplied by 1.1, the overflow encountered in double_scalars runtime warning is received.

It must be kept in mind that this is only a warning and that it continues to run.

However, because the number would be too large, it cannot return one. Instead, it provides inf.

Though some valid calculations use infinity, some produce nan, which stands for no number, like in the below program.

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)

Output:

inf inf inf inf -inf 0.0 inf nan nan

The above program shows all the possible scenarios where infinity and nan can be encountered.

Sometimes a program does not enter the state of overflow or display infinity or NaN but produces results that are not only inaccurate but significantly incorrect.

In the below example, an array A is declared of data type int64. This data type stores different bits depending on the machine used.

When a value stored inside this variable is raised to the power of itself, the program outputs insignificant values instead of undergoing an overflow or displaying infinity.

For example, a positive integer like 50, when raised to the power of itself, ought to yield a positive integer, but when the below code is executed, the result is a negative value.

import numpy as np

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

Output:

-6646187150092009472

But we get the appropriate result when the same value is stored in a datatype like double or longdouble.

import numpy as np

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

Output:

8.881784197001252e+84

Note: It must be kept in mind that the runtime warning overflow encountered in double_scalars can be evaded only until the numbers ply along the data type’s range.

Though going outside that range does not interrupt the program and create an error, ignoring the warning overflow encountered in double_scalars can come at the cost of rendering unstable results.

Some Other Overflow Warning That Arises in Python

This section will teach us to catch overflow errors other than double scalars. There are mainly two other overflows that arise often.

  1. Overflow encountered in power

    When the numpy subroutine power is used to raise a number to the power of itself, and the resultant is outside the range, it throws the error overflow encountered in power.

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

    Output:

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

    This kind of overflow is encountered during operations with exponents. Raising a number to the power of huge exponents yields inf while dividing it with that figure yields a zero.

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

    Output:

    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)))
    

Conclusion

This article explains how to evade runtime warnings like overflow encountered in double_scalars, etc. After going through this article, the reader can catch overflow errors easily.