decimal — 고정 소수점 및 부동 소수점 십진 산술

decimal — 고정 소수점 및 부동 소수점 십진 산술

decimal 모듈은 빠르고 정확하게 반올림되는 십진 부동 소수점 산술을 지원합니다. float 데이터 타입에 비해 여러 장점을 제공합니다.

출처: Python documentation

본문

  • Decimal은 "사람을 염두에 두고 설계된 부동 소수점 모델에 기반하며, 필연적으로 최고 지도 원칙을 가집니다. 컴퓨터는 사람이 학교에서 배우는 산술과 같은 방식으로 동작하는 산술을 제공해야 합니다."
  • Decimal 숫자는 정확히 표현될 수 있습니다. 반대로 1.1이나 2.2 같은 숫자는 이진 부동 소수점에서 정확한 표현이 없습니다. 일반 사용자는 1.1 + 2.2가 이진 부동 소수점처럼 3.3000000000000003으로 표시되기를 기대하지 않습니다.
  • 정확성은 산술에도 이어집니다. 십진 부동 소수점에서 0.1 + 0.1 + 0.1 - 0.3은 정확히 0입니다. 이진 부동 소수점에서는 결과가 5.5511151231257827e-017입니다. 0에 가깝지만 차이가 신뢰할 수 있는 동등성 테스트를 방해하고 차이가 누적될 수 있습니다. 이런 이유로 decimal은 엄격한 동등성 불변식이 있는 회계 애플리케이션에서 선호됩니다.
  • decimal 모듈은 유효 자릿수(significant places) 개념을 통합하여 1.30 + 1.202.50이 됩니다. 끝의 0은 유효성을 나타내기 위해 유지되며 이는 통화 애플리케이션의 관례적인 표현입니다. 곱셈은 "교과서 방식"으로 피승수의 모든 자릿수를 사용합니다. 예를 들어 1.3 * 1.21.56, 1.30 * 1.201.5600입니다.
  • 하드웨어 기반 이진 부동 소수점과 달리 decimal 모듈은 사용자가 변경할 수 있는 정밀도(기본 28 자리)를 가지며, 주어진 문제에 필요한 만큼 클 수 있습니다.
  • 이진 부동 소수점과 십진 부동 소수점 모두 공표된 표준으로 구현됩니다. decimal 모듈은 표준의 필요 부분을 모두 노출하며 프로그래머가 반올림과 신호 처리에 대한 완전한 제어를 가집니다.

모듈 설계는 십진 숫자(decimal number), 산술 컨텍스트(context), 신호(signal)라는 세 가지 개념을 중심으로 합니다.

십진 숫자는 불변입니다. 부호, 계수 자릿수, 지수를 가집니다. 유효성을 보존하기 위해 계수 자릿수는 끝의 0을 자르지 않습니다. Decimal은 Infinity, -Infinity, NaN 같은 특수 값도 포함하며, 표준은 -0+0을 구분합니다.

산술 컨텍스트는 정밀도, 반올림 규칙, 지수 제한, 연산 결과를 나타내는 플래그, 그리고 신호를 예외로 취급할지 결정하는 트랩 활성화를 지정하는 환경입니다. 반올림 옵션으로는 ROUND_CEILING, ROUND_DOWN, ROUND_FLOOR, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_UP, ROUND_05UP이 있습니다.

신호는 연산 중 발생하는 예외적 조건의 그룹입니다. 애플리케이션의 필요에 따라 무시되거나 정보용으로 간주되거나 예외로 취급될 수 있습니다. 신호로는 Clamped, InvalidOperation, DivisionByZero, Inexact, Rounded, Subnormal, Overflow, Underflow, FloatOperation이 있습니다. 각 신호에는 플래그와 트랩 활성화가 있으며, 신호가 발생하면 플래그가 1로 설정되고 트랩이 활성화되어 있으면 예외가 발생합니다. 플래그는 고정(sticky)되어 있어 계산을 모니터링하기 전에 사용자가 리셋해야 합니다.

빠른 시작

보통 from decimal import *로 모듈을 import하고 getcontext()로 현재 컨텍스트를 본 뒤 필요하면 정밀도, 반올림, 활성 트랩에 새 값을 설정합니다:

>>> from decimal import *
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
        capitals=1, clamp=0, flags=[], traps=[Overflow, DivisionByZero, InvalidOperation])
>>> getcontext().prec = 7       # Set a new precision

Decimal 인스턴스는 정수, 문자열, float, 튜플로 만들 수 있습니다. Decimal(10), Decimal('3.14'), Decimal(3.14), Decimal((0, (3, 1, 4), -2))처럼 정수나 float로부터의 생성은 그 값의 정확한 변환을 수행합니다. FloatOperation 신호가 트랩되면 생성자나 순서 비교에서 decimal과 float의 우연한 혼합이 예외를 발생시킵니다.

더 알아보기 (Learn more)