Solved: Overflow Encountered in Double_Scalars in Python

Jay Shaw Oct 10, 2023

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.