해결됨: Python의 Double_Scalars에서 오버플로 발생

Jay Shaw 2023년6월21일
  1. Python에서 double_scalars에서 발생한 오버플로 오류의 원인
  2. double_scalars에서 발생한 오버플로 오류를 방지하는 방법
  3. Python에서 발생하는 다른 오버플로 경고
  4. 결론
해결됨: Python의 Double_Scalars에서 오버플로 발생

Python 라이브러리 패키지 Numpy에 정의된 이중 스칼라는 double 데이터 유형의 값입니다. 이 데이터 유형은 큰 숫자를 계산하는 데 사용됩니다.

종종 이러한 숫자의 크기가 너무 커서 프로그램이 오버플로 상태로 실행되고 double_scalars에서 오버플로가 발생했습니다라는 경고가 표시됩니다. 이 문서에서는 이중 스칼라의 오버플로, 이 문제를 일으키는 특정 상황 및 해결 방법에 대해 설명합니다.

Python에서 double_scalars에서 발생한 오버플로 오류의 원인

이중 스칼라는 더 높고 더 낮은 범위와 함께 제공됩니다. 더 작은 숫자의 산술 계산은 정상적으로 결과를 생성하지만 이러한 숫자가 특정 임계값을 넘어 거듭날 때 double_scalars에서 오버플로 발생 문제가 발생합니다.

이해를 돕기 위해 예를 들어보겠습니다.

이 프로그램은 이중 스칼라 범위를 표시하고 범위 경계에 계산을 표시한 다음 오버플로 오류가 발생한 지점을 표시합니다. “double_scalars에서 오버플로 발생"이라는 경고가 표시됩니다.

이 프로그램은 Python 패키지 numpy를 가져오고 오류 처리를 all='warn'으로 설정하여 런타임 중에 오류에 대한 경고를 발생시킵니다.

import numpy as np

np.seterr(all="warn")

numpy 데이터 유형의 범위를 찾기 위해 finfo 데이터 유형 루틴을 사용합니다. 이 루틴은 호출될 때 시스템 내부의 이중 스칼라와 같은 부동 소수점 유형의 한계를 반환합니다.

이중 스칼라의 하한, 즉 최소값을 찾으려면 np.finfo(np.double).min과 같은 구문이 필요합니다. 이 프로그램에서 최소값과 최대값은 minmax 서브루틴을 사용하여 찾습니다.

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

범위의 경계에서 값을 찾기 위해 double 데이터 유형의 numpy 배열 A가 생성됩니다. 이 배열에는 값이 143인 단일 요소가 있습니다.

0번째 인덱스 값은 변수 a에 복사되어 이 배열에서 이 값을 자체적으로 거듭제곱합니다. 그런 다음 이 변수는 a**a를 사용하여 자체적으로 거듭제곱됩니다.

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

프로그램은 위 코드까지는 정상적으로 실행되지만 주어진 double scalar 범위 밖에서 연산이 실행되면 double_scalars에서 오버플로우 발생이 발생합니다.

이 경고를 재현하기 위해 이전 어레이에서 사용된 것보다 더 큰 값을 저장하는 새 어레이 B가 생성됩니다.

이 값이 자신의 거듭제곱으로 올라가면 프로그램은 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)

출력:

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

double_scalars에서 발생한 오버플로 오류를 방지하는 방법

위의 예에서 볼 수 있듯이 데이터 유형의 가장 높은 범위를 넘으면 double_scalars에서 오버플로 발생이 발생할 수 있습니다. 이 오류를 피하는 가장 좋은 방법은 주어진 범위 내에서 작업하거나 계산 능력을 높이는 것입니다.

그러나 데이터 유형이 병목 현상을 일으키는 경우가 있습니다. 다음은 동일한 경고를 전달하는 프로그램입니다.

데이터 유형 float32의 첫 번째 배열은 값 143이 거듭제곱될 때 오버플로됩니다. 이것은 float가 최대 8비트의 지수를 전달할 수 있기 때문에 발생합니다.

반면에 데이터 유형 double은 최대 11 지수 비트의 계산을 견딜 수 있으므로 오버플로에 빠지지 않고 결과를 생성합니다.

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)

출력:

프로그램이 a**a를 실행하려고 할 때 이중 스칼라와 유사한 오버플로가 발생하고 출력에 inf가 표시되며 이는 결과가 무한함을 의미합니다.

그러나 다른 데이터 유형을 사용할 때 원하는 결과를 얻습니다.

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)

일부 계산에서는 무한대를 사용하여 범위를 벗어난 결과를 표현하므로 결과가 엄청납니다.

float64와 같은 데이터 유형의 숫자 범위는 -1.79769313486e+308에서 1.79769313486e+308까지입니다. 크거나 작으면 오버플로가 발생하는 것으로 관찰됩니다.

예를 들어, 최대 범위 - np.double(1.79769313486e+308)1.1을 곱하면 double_scalars에서 오버플로 발생 런타임 경고가 수신됩니다.

이는 경고일 뿐이며 계속 실행된다는 점을 명심해야 합니다.

그러나 숫자가 너무 크므로 1을 반환할 수 없습니다. 대신 inf를 제공합니다.

일부 유효한 계산은 무한대를 사용하지만 일부는 아래 프로그램과 같이 숫자가 없음을 나타내는 nan을 생성합니다.

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)

출력:

inf inf inf inf -inf 0.0 inf nan nan

위의 프로그램은 무한대와 nan이 발생할 수 있는 모든 가능한 시나리오를 보여줍니다.

때때로 프로그램은 오버플로 상태에 들어가지 않거나 무한대 또는 NaN을 표시하지만 부정확할 뿐만 아니라 상당히 부정확한 결과를 생성합니다.

아래 예에서 배열 A는 데이터 유형 int64로 선언됩니다. 이 데이터 유형은 사용되는 기계에 따라 다른 비트를 저장합니다.

이 변수에 저장된 값을 거듭제곱하면 프로그램은 오버플로나 무한대를 표시하는 대신 무의미한 값을 출력합니다.

예를 들어 50과 같은 양의 정수는 거듭제곱하면 양의 정수가 되어야 하는데 아래 코드를 실행하면 결과는 음의 값이 된다.

import numpy as np

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

출력:

-6646187150092009472

그러나 동일한 값이 double 또는 longdouble과 같은 데이터 유형에 저장될 때 적절한 결과를 얻습니다.

import numpy as np

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

출력:

8.881784197001252e+84

참고: 런타임 경고 double_scalars에서 발생한 오버플로는 데이터 유형의 범위를 따라 숫자가 늘어날 때까지만 피할 수 있다는 점을 명심해야 합니다.

이 범위를 벗어나도 프로그램이 중단되거나 오류가 발생하지는 않지만 double_scalars에서 오버플로가 발생했습니다라는 경고를 무시하면 불안정한 결과를 렌더링하는 비용이 발생할 수 있습니다.

Python에서 발생하는 다른 오버플로 경고

이 섹션에서는 이중 스칼라 이외의 오버플로 오류를 잡는 방법을 알려줍니다. 주로 자주 발생하는 다른 두 가지 오버플로가 있습니다.

  1. power에서 발생한 오버플로

    numpy 서브루틴 power를 사용하여 숫자를 자신의 거듭제곱으로 올리고 그 결과가 범위를 벗어나면 overflow scheduled in power 오류가 발생합니다.

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

    출력:

    inf
    C:/Users/main.py:12: RuntimeWarning: overflow encountered in power
    print(np.power(143, 144, dtype=np.double))
    
  2. exp에서 발생한 오버플로

    이러한 종류의 오버플로는 지수를 사용하는 작업 중에 발생합니다. 큰 지수의 거듭제곱으로 숫자를 올리면 inf가 생성되고 해당 숫자로 나누면 0이 생성됩니다.

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

    출력:

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

결론

이 기사에서는 double_scalars에서 오버플로 발생 등과 같은 런타임 경고를 피하는 방법에 대해 설명합니다. 이 기사를 살펴본 후 독자는 오버플로 오류를 쉽게 잡을 수 있습니다.