널리 사용되는 프로그래밍 언어인 Python은 수치 컴퓨팅 작업에 탁월하지만 부동 소수점 연산으로 인한 문제로부터 자유롭지는 않습니다. Python의 부동 소수점 숫자는 실수의 근사치이므로 다음과 같습니다. 반올림 오류, 정밀도 손실 및 취소 계산을 망칠 수 있습니다. 우리는 할 수 있다 이상한 결과를 찾아 이러한 오류를 찾아보세요. 그리고 도구를 사용해서numpy.finfo>에게 모니터 정밀도 . 약간의 주의와 영리한 트릭을 사용하면 다음과 같은 결과를 얻을 수 있습니다. 이러한 오류를 확인하세요 Python 계산의 신뢰성을 보장합니다. 이 기사에서는 부동 소수점 오류의 복잡성을 살펴보겠습니다. 파이썬 .
부동 소수점 숫자란 무엇입니까?
부동 소수점 숫자는 컴퓨터에서 실수를 나타내는 효율적인 방법입니다. 이는 세 부분으로 구성됩니다.
- 중요한: 숫자를 나타내는 실제 숫자(예: 3.14159)
- 멱지수: 유효 숫자를 왼쪽이나 오른쪽으로 이동할 위치를 알려줍니다(예: 3.14159 x 10^-2의 -2).
- 베이스: 일반적으로 컴퓨터의 경우 2이며 숫자가 내부적으로 표현되는 방식을 결정합니다.
부동 소수점 오류는 왜 발생합니까?
부동 소수점 오류는 컴퓨터가 유한한 수의 비트를 사용하여 실수를 저장하여 근사치 및 잠재적인 부정확성을 초래하기 때문에 발생합니다. 부동 소수점 숫자에는 본질적인 제한이 있습니다.
- 유한 정밀도: 유효 숫자에는 제한된 수의 자릿수만 저장할 수 있습니다. 반올림 오류 정확한 소수를 나타낼 때.
- 정밀도 손실: 덧셈이나 뺄셈과 같은 연산은 정밀도를 더욱 감소시켜 반올림 효과를 더욱 악화시킬 수 있습니다.
- 언더플로우/오버플로우: 매우 작거나 큰 숫자는 표현 가능한 범위를 벗어날 수 있습니다. 언더플로 (0이 됨) 또는 과다 (무한대가 됨)
부동 소수점 오류 유형
a) 반올림 오류: 가장 일반적인 현상은 부동 소수점의 제한된 정밀도에 맞게 정확한 소수점을 근사화해야 할 때 발생합니다.
b) 정밀도 손실: 후속 작업에서는 반올림 오류가 점차 누적되어 최종 결과가 크게 부정확해질 수 있습니다.
c) 치명적인 취소: 거의 같은 수를 반대 부호로 뺄 때 유효 숫자가 상쇄되어 작고 부정확한 결과가 남습니다.
d) 오버플로/언더플로: 이는 계산이 표현 가능한 부동 소수점 값 범위를 초과하여 부정확하거나 의미 없는 결과를 초래할 때 발생합니다.
부동 소수점 오류 감지
- 예상치 못한 결과 관찰: 계산된 값을 예상 결과와 비교하거나 데이터를 시각화하면 종종 오류로 인해 발생하는 불일치가 드러날 수 있습니다.
- 다음과 같은 라이브러리를 사용하여
numpy.finfo>: 다음과 같은 도서관numpy>같은 도구를 제공finfo>다양한 부동 소수점 데이터 유형의 정밀도와 제한 사항을 확인합니다.
Python 부동 소수점 오류
여기서는 Python의 부동 소수점 오류를 설명하는 다양한 유형의 예제에 대해 설명합니다.
10진수를 2진수로 변환할 때 정밀도 손실
이 예에서는 10진수 0.1이 2진수로 변환됩니다. 0.1의 무한 이진 확장으로 인해 유한한 수의 비트만 사용되므로 정밀도가 손실됩니다.
파이썬3
decimal_number>=> 0.1> binary_representation>=> format>(decimal_number,>'.30f'>)># 30 decimal places> print>(f>'Decimal: {decimal_number}
Binary: {binary_representation}'>)> |
연결리스트 자바
>
>
산출:
Decimal: 0.1 Binary: 0.100000000000000005551115123126>
반올림 오류
여기서 1/3을 3번 더한 결과는 1.0이 될 것으로 예상됩니다. 그러나 1/3을 나타내는 데 있어서 반올림 오류로 인해 그 합이 정확히 1.0이 아닐 수도 있습니다.
파이썬3
result>=> 1.0> /> 3.0> sum_result>=> result>+> result>+> result> print>(f>'Expected Result: 1.0
Actual Result: {sum_result}'>)> |
>
>
산출:
Expected Result: 1.0 Actual Result: 1.0>
반복 계산의 누적 오류
이 예에서는 반복 계산에서 누적 오류가 어떻게 발생할 수 있는지 보여줍니다. 0.1을 10번 더하면 부동 소수점 정밀도 제한으로 인해 정확한 1.0 결과가 나오지 않을 수 있습니다.
파이썬3
total>=> 0.0> for> i>in> range>(>10>):> >total>+>=> 0.1> print>(f>'Expected Result: 1.0
Actual Result: {total}'>)> |
>
>
산출:
Expected Result: 1.0 Actual Result: 0.9999999999999999>
비교 문제
이 경우 0.1과 0.2의 합을 0.3과 비교하면 예상한 결과가 나오지 않을 수 있습니다.True>부동 소수점 숫자의 고유한 부정확성으로 인해 발생합니다.
파이썬3
a>=> 0.1> +> 0.2> b>=> 0.3> print>(f>'a: {a}
b: {b}
Equal: {a == b}'>)> |
>
>
산출:
a: 0.30000000000000004 b: 0.3 Equal: False>
계산에서 예상치 못한 결과가 발생함
여기서 뺄셈은1e16>합계에서(1e16 + 1)>1이 나올 것으로 예상되지만 부동 소수점 오류로 인해 결과가 정확히 1이 아닐 수도 있습니다.
파이썬3
a>=> 0.1> +> 0.2> b>=> 0.3> print>(f>'a: {a}
b: {b}
Equal: {a == b}'>)> |
>
>
산출:
Expected Result: 1 Actual Result: 0.0>
부동 소수점 정밀도 이해
여기서 우리는 부동 소수점 정밀도를 이해할 것입니다: Python의 1.2 – 1.0 이상 현상-
표현 문제
1.2 – 1.0 = 0.2로 알려져 있습니다. 그러나 Python에서 동일한 작업을 수행하려고 하면 결과에 놀랄 것입니다.
>>> 1.2 - 1.0>
산출:
0.199999999999999996>
이것은 Python의 버그로 간주될 수 있지만 그렇지 않습니다. 이는 Python과는 거의 관련이 없으며 기본 플랫폼이 부동 소수점 숫자를 처리하는 방법과 훨씬 더 관련이 있습니다. 이는 시스템 내부에서 부동 소수점 숫자를 처리할 때 발생하는 일반적인 경우입니다. 이는 고정된 수의 이진수를 사용하여 소수를 표현하는 부동 소수점 숫자의 내부 표현에서 발생하는 문제입니다. 일부 십진수를 이진수로 표현하는 것은 어렵기 때문에 많은 경우 작은 반올림 오류가 발생합니다. 우리는 십진수 수학에서도 비슷한 경우를 알고 있습니다. 많은 결과가 고정된 십진수 자릿수로 표시될 수 없습니다. 예
10 / 3 = 3.33333333.......>
이 경우 1.2를 예로 들면 0.2를 이진수로 표현하면 0.00110011001100110011001100… 등이 됩니다. 이 무한한 십진수를 내부적으로 저장하는 것은 어렵습니다. 일반적으로 float 객체의 값은 고정된 정밀도( 일반적으로 53비트 ). 그래서 우리는 대표합니다 1.2 내부적으로는,
1.0011001100110011001100110011001100110011001100110011>
이는 정확히 다음과 같습니다.
1.1999999999999999555910790149937383830547332763671875>
부동 소수점 오류 처리
여기에서는 Python에서 부동 소수점 오류를 처리하는 방법에 대한 다양한 예를 설명합니다.
특정 소수점 이하 자리로 반올림
결과를 특정 소수 자릿수(예: 2)로 반올림하면 작은 부동 소수점 오류의 영향을 완화할 수 있습니다.
파이썬3
result>=> 1.2> -> 1.0> rounded_result>=> round>(result,>2>)> print>(f>'Original Result: {result}
Rounded Result: {rounded_result}'>)> |
>
>
산출:
Original Result: 0.19999999999999996 Rounded Result: 0.2>
높은 정밀도를 위해 Decimal 클래스 사용
그만큼decimal>모듈은 다음을 제공합니다.Decimal>클래스로 인해 더 높은 정밀도의 연산이 가능해졌습니다. 정밀도 설정getcontext().prec>특정 계산의 정밀도를 관리하는 데 도움이 될 수 있습니다.
파이썬3
from> decimal>import> Decimal, getcontext> getcontext().prec>=> 4> # Set precision to 4 decimal places> result>=> Decimal(>'1.2'>)>-> Decimal(>'1.0'>)> print>(f>'High Precision Result: {result}'>)> |
>
>
산출:
High Precision Result: 0.2>
정확한 표현을 위해 분수 사용하기
그만큼fractions>모듈을 사용하면 부동 소수점 오류를 방지하면서 정확한 분수 표현으로 작업할 수 있습니다.
파이썬3
from> fractions>import> Fraction> result>=> Fraction(>'1.2'>)>-> Fraction(>'1.0'>)> print>(f>'Exact Fractional Result: {result}'>)> |
>
>
산출:
Exact Fractional Result: 1/5>
Decimal로 중간 결과 처리하기
사용Decimal>float로 다시 변환하기 전에 누적 오류를 최소화하기 위한 중간 계산용 클래스입니다.
파이썬3
from> decimal>import> Decimal, getcontext> getcontext().prec>=> 6> # Set precision to 6 decimal places> intermediate_result>=> Decimal(>'1.2'>)>-> Decimal(>'1.0'>)> final_result>=> float>(intermediate_result)># Convert back to float if needed> print>(f>'Intermediate Result: {intermediate_result}
Final Result: {final_result}'>)> |
>
>
산출:
Intermediate Result: 0.2 Final Result: 0.2>
결론
아직도, 왜인지 생각하고 계시나요? 파이썬은 이 문제를 해결하지 못합니다 , 실제로는 Python과 관련이 없습니다. 이는 기본 c 플랫폼이 부동 소수점 숫자를 처리하는 방식이기 때문에 발생하며 궁극적으로 부정확함으로 인해 우리는 항상 숫자를 고정된 숫자의 문자열로 기록해 왔습니다. 이는 이진 부동 소수점의 본질에 속합니다. 이는 버그가 아닙니다. 파이썬 또는 씨 , 코드의 버그도 아닙니다. 일부 언어는 기본적으로 또는 모든 출력 모드에서 차이를 표시하지 않을 수 있지만 하드웨어의 부동 소수점 연산을 지원하는 모든 언어에서 동일한 종류의 동작을 볼 수 있습니다. 정확한 정밀도가 필요한 수학 문제에 관심을 두거나 조건문 내에서 이를 사용할 때 이 동작을 고려해야 합니다. 확인하다 부동 소수점 더 많은 동작에 대해서는 Python 문서의 섹션을 참조하세요.
자주 묻는 질문(FAQ)
1. Python의 부동 소수점 오류란 무엇입니까?
Python의 부동 소수점 오류는 부동 소수점 숫자로 작업할 때 예상 결과와 실제 결과 사이의 불일치를 의미하며, 이는 이진 기반 시스템에서 실수를 표현하는 한계로 인해 발생합니다.
2. 왜? 1.2 - 1.0> 같지 않다 0.2> 파이썬에서?
이러한 불일치는 십진수를 이진수로 표현하는 데 따른 본질적인 문제로 인해 발생합니다. 내부 이진 표현 중에 반올림 오류가 발생하여 예상치 못한 결과가 발생합니다.
삼. 부동 소수점 오류는 Python의 버그입니까?
아니요, Python의 버그는 아닙니다. 부동 소수점 숫자가 내부적으로 표현되는 방식과 관련된 컴퓨팅의 일반적인 문제입니다. Python은 부동 소수점 연산에 대한 IEEE 754 표준을 준수합니다.
4. 부동 소수점 결과를 특정 소수 자릿수로 반올림하려면 어떻게 해야 합니까?
당신은 사용할 수 있습니다
round()>부동 소수점 결과를 특정 소수 자릿수로 반올림하는 함수입니다. 예를 들어,rounded_result = round(result, 2)>.
5. 이것은 decimal> 모듈이며 부동 소수점 오류를 처리하는 데 어떻게 도움이 됩니까?
그만큼
decimal>모듈은 다음을 제공합니다.Decimal>더 높은 정밀도의 연산을 위한 클래스입니다. 정밀도 설정 및 사용Decimal>부동 소수점 오류를 완화하는 데 도움이 될 수 있습니다.