"decimal" --- Decimal fixed-point and floating-point arithmetic
***************************************************************

**소스 코드:** Lib/decimal.py

======================================================================

The "decimal" module provides support for fast correctly rounded
decimal floating-point arithmetic. It offers several advantages over
the "float" datatype:

* Decimal "은 사람을 염두에 두고 설계된 부동 소수점 모델에 기반하고,
  필연적으로 최고 원리를 갖습니다 -- 컴퓨터는 사람들이 학교에서 배우는
  산술과 같은 방식으로 동작하는 산술을 반드시 제공해야 한다." -- 십진
  산술 명세에서 발췌.

* Decimal numbers can be represented exactly.  In contrast, numbers
  like "1.1" and "2.2" do not have exact representations in binary
  floating point. End users typically would not expect "1.1 + 2.2" to
  display as "3.3000000000000003" as it does with binary floating
  point.

* The exactness carries over into arithmetic.  In decimal floating
  point, "0.1 + 0.1 + 0.1 - 0.3" is exactly equal to zero.  In binary
  floating point, the result is "5.5511151231257827e-017".  While near
  to zero, the differences prevent reliable equality testing and
  differences can accumulate. For this reason, decimal is preferred in
  accounting applications which have strict equality invariants.

* The decimal module incorporates a notion of significant places so
  that "1.30 + 1.20" is "2.50".  The trailing zero is kept to indicate
  significance. This is the customary presentation for monetary
  applications. For multiplication, the "schoolbook" approach uses all
  the figures in the multiplicands.  For instance, "1.3 * 1.2" gives
  "1.56" while "1.30 * 1.20" gives "1.5600".

* 하드웨어 기반 이진 부동 소수점과는 달리, decimal 모듈은 사용자가 변
  경할 수 있는 정밀도(기본값은 28자리)를 가지며, 주어진 문제에 따라 필
  요한 만큼 커질 수 있습니다:

  >>> from decimal import *
  >>> getcontext().prec = 6
  >>> Decimal(1) / Decimal(7)
  Decimal('0.142857')
  >>> getcontext().prec = 28
  >>> Decimal(1) / Decimal(7)
  Decimal('0.1428571428571428571428571429')

* 이진 및 십진 부동 소수점 모두 출판된 표준에 따라 구현됩니다. 내장
  float 형이 기능의 적당한 부분만을 드러내지만, decimal 모듈은 표준의
  모든 필수 부분을 노출합니다. 필요한 경우, 프로그래머는 자리 올림
  (rounding) 및 신호(signal) 처리를 완전히 제어할 수 있습니다. 여기에
  는 정확하지 않은 연산을 차단하기 위한 예외를 사용하여 정확한 산술을
  강제하는 옵션이 포함됩니다.

* decimal 모듈은 "편견 없이, (때로 고정 소수점 산술이라고도 불리는) 정
  확한 자리 올림 없는 십진 산술과 자리 올림 있는 부동 소수점 산술을 모
  두" 지원하도록 설계되었습니다. -- 십진 산술 명세에서 발췌.

모듈 설계의 중심 개념은 세 가지입니다: 십진수, 산술을 위한 컨텍스트,
신호(signal).

A decimal number is immutable.  It has a sign, coefficient digits, and
an exponent.  To preserve significance, the coefficient digits do not
truncate trailing zeros.  Decimals also include special values such as
"Infinity", "-Infinity", and "NaN".  The standard also differentiates
"-0" from "+0".

산술 컨텍스트는 정밀도, 자리 올림 규칙, 지수에 대한 제한, 연산 결과를
나타내는 플래그 및 신호가 예외로 처리될지를 결정하는 트랩 활성화기
(trap enabler)를 지정하는 환경입니다. 자리 올림 옵션에는
"ROUND_CEILING", "ROUND_DOWN", "ROUND_FLOOR", "ROUND_HALF_DOWN",
"ROUND_HALF_EVEN", "ROUND_HALF_UP", "ROUND_UP" 및 "ROUND_05UP" 가 있습
니다.

신호는 계산 과정에서 발생하는 예외적인 조건의 그룹입니다. 응용 프로그
램의 필요에 따라, 신호가 무시되거나, 정보로 간주하거나, 예외로 처리될
수 있습니다. decimal 모듈의 신호는 "Clamped", "InvalidOperation",
"DivisionByZero", "Inexact", "Rounded", "Subnormal", "Overflow",
"Underflow", "FloatOperation" 입니다.

각 신호에는 플래그와 트랩 활성화기가 있습니다. 신호와 만났을 때, 플래
그가 1로 설정되고 트랩 활성화기가 1로 설정된 경우, 예외가 발생합니다.
플래그는 상태가 유지되므로(sticky) 계산을 감시하기 전에 재설정할 필요
가 있습니다.

더 보기:

  * IBM's General Decimal Arithmetic Specification, The General
    Decimal Arithmetic Specification.


Quick-start tutorial
====================

decimal을 사용하는 일반적인 시작은 모듈을 임포트하고, "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 instances can be constructed from integers, strings, floats,
or tuples. Construction from an integer or a float performs an exact
conversion of the value of that integer or float.  Decimal numbers
include special values such as "NaN" which stands for "Not a number",
positive and negative "Infinity", and "-0":

   >>> getcontext().prec = 28
   >>> Decimal(10)
   Decimal('10')
   >>> Decimal('3.14')
   Decimal('3.14')
   >>> Decimal(3.14)
   Decimal('3.140000000000000124344978758017532527446746826171875')
   >>> Decimal((0, (3, 1, 4), -2))
   Decimal('3.14')
   >>> Decimal(str(2.0 ** 0.5))
   Decimal('1.4142135623730951')
   >>> Decimal(2) ** Decimal('0.5')
   Decimal('1.414213562373095048801688724')
   >>> Decimal('NaN')
   Decimal('NaN')
   >>> Decimal('-Infinity')
   Decimal('-Infinity')

"FloatOperation" 신호를 트랩 하는 경우, 실수로 생성자나 대소비교에서
Decimal 수와 실수(float)를 혼합하면 예외가 발생합니다:

   >>> c = getcontext()
   >>> c.traps[FloatOperation] = True
   >>> Decimal(3.14)
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
   >>> Decimal('3.5') < 3.7
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
   >>> Decimal('3.5') == 3.5
   True

Added in version 3.3.

새로운 Decimal의 유효 숫자는 입력된 숫자의 개수에 의해서만 결정됩니다.
컨텍스트 정밀도 및 자리 올림은 오직 산술 연산 중에만 작용합니다.

   >>> getcontext().prec = 6
   >>> Decimal('3.0')
   Decimal('3.0')
   >>> Decimal('3.1415926535')
   Decimal('3.1415926535')
   >>> Decimal('3.1415926535') + Decimal('2.7182818285')
   Decimal('5.85987')
   >>> getcontext().rounding = ROUND_UP
   >>> Decimal('3.1415926535') + Decimal('2.7182818285')
   Decimal('5.85988')

C 버전의 내부 제한을 초과하면, Decimal 을 만들 때 "InvalidOperation"
를 일으킵니다:

   >>> Decimal("1e9999999999999999999")
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]

버전 3.3에서 변경.

Decimals interact well with much of the rest of Python.  Here is a
small decimal floating-point flying circus:

   >>> data = list(map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split()))
   >>> max(data)
   Decimal('9.25')
   >>> min(data)
   Decimal('0.03')
   >>> sorted(data)
   [Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('1.87'),
    Decimal('2.35'), Decimal('3.45'), Decimal('9.25')]
   >>> sum(data)
   Decimal('19.29')
   >>> a,b,c = data[:3]
   >>> str(a)
   '1.34'
   >>> float(a)
   1.34
   >>> round(a, 1)
   Decimal('1.3')
   >>> int(a)
   1
   >>> a * 5
   Decimal('6.70')
   >>> a * b
   Decimal('2.5058')
   >>> c % a
   Decimal('0.77')

그리고 Decimal에는 몇 가지 수학 함수도 있습니다:

>>> getcontext().prec = 28
>>> Decimal(2).sqrt()
Decimal('1.414213562373095048801688724')
>>> Decimal(1).exp()
Decimal('2.718281828459045235360287471')
>>> Decimal('10').ln()
Decimal('2.302585092994045684017991455')
>>> Decimal('10').log10()
Decimal('1')

The "quantize()" method rounds a number to a fixed exponent.  This
method is useful for monetary applications that often round results to
a fixed number of places:

>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
Decimal('7.32')
>>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)
Decimal('8')

위에서 보듯이, "getcontext()" 함수는 현재 컨텍스트에 액세스하고 설정을
변경할 수 있게 합니다. 이 방법은 대부분 응용 프로그램의 요구를 충족시
킵니다.

고급 작업을 위해, Context() 생성자를 사용하여 대체 컨텍스트를 만드는
것이 유용할 수 있습니다. 대체 컨텍스트를 활성화하려면, "setcontext()"
함수를 사용하십시오.

표준에 따라, "decimal" 모듈은 당장 사용할 수 있는 두 개의 표준 컨텍스
트 "BasicContext" 와 "ExtendedContext" 를 제공합니다. 특히 전자는 많은
트랩이 활성화되어있어 디버깅에 유용합니다:

   >>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)
   >>> setcontext(myothercontext)
   >>> Decimal(1) / Decimal(7)
   Decimal('0.142857142857142857142857142857142857142857142857142857142857')

   >>> ExtendedContext
   Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
           capitals=1, clamp=0, flags=[], traps=[])
   >>> setcontext(ExtendedContext)
   >>> Decimal(1) / Decimal(7)
   Decimal('0.142857143')
   >>> Decimal(42) / Decimal(0)
   Decimal('Infinity')

   >>> setcontext(BasicContext)
   >>> Decimal(42) / Decimal(0)
   Traceback (most recent call last):
     File "<pyshell#143>", line 1, in -toplevel-
       Decimal(42) / Decimal(0)
   DivisionByZero: x / 0

Contexts also have signal flags for monitoring exceptional conditions
encountered during computations.  The flags remain set until
explicitly cleared, so it is best to clear the flags before each set
of monitored computations by using the "clear_flags()" method.

   >>> setcontext(ExtendedContext)
   >>> getcontext().clear_flags()
   >>> Decimal(355) / Decimal(113)
   Decimal('3.14159292')
   >>> getcontext()
   Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
           capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[])

The *flags* entry shows that the rational approximation to pi was
rounded (digits beyond the context precision were thrown away) and
that the result is inexact (some of the discarded digits were non-
zero).

Individual traps are set using the dictionary in the "traps" attribute
of a context:

   >>> setcontext(ExtendedContext)
   >>> Decimal(1) / Decimal(0)
   Decimal('Infinity')
   >>> getcontext().traps[DivisionByZero] = 1
   >>> Decimal(1) / Decimal(0)
   Traceback (most recent call last):
     File "<pyshell#112>", line 1, in -toplevel-
       Decimal(1) / Decimal(0)
   DivisionByZero: x / 0

대부분 프로그램은 프로그램 시작 시에 한 번만 현재 컨텍스트를 조정합니
다. 그리고, 많은 응용 프로그램에서, 데이터는 루프 내에서 단일형변환으
로 "Decimal"로 변환되어, 프로그램 대부분은 다른 파이썬 숫자 형과 별로
다르지 않게 데이터를 조작합니다.


Decimal 객체
============

class decimal.Decimal(value='0', context=None)

   *value* 를 기반으로 새 "Decimal" 객체를 만듭니다.

   *value* 는 정수, 문자열, 튜플, "float" 또는 다른 "Decimal" 객체일
   수 있습니다. *value* 가 주어지지 않으면, "Decimal('0')" 을 반환합니
   다. *value* 가 문자열이면, 앞뒤의 공백 문자 및 밑줄이 제거된 후 십
   진수 문자열 문법에 맞아야 합니다:

      sign           ::=  '+' | '-'
      digit          ::=  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
      indicator      ::=  'e' | 'E'
      digits         ::=  digit [digit]...
      decimal-part   ::=  digits '.' [digits] | ['.'] digits
      exponent-part  ::=  indicator [sign] digits
      infinity       ::=  'Infinity' | 'Inf'
      nan            ::=  'NaN' [digits] | 'sNaN' [digits]
      numeric-value  ::=  decimal-part [exponent-part] | infinity
      numeric-string ::=  [sign] numeric-value | [sign] nan

   Other Unicode decimal digits are also permitted where "digit"
   appears above.  These include decimal digits from various other
   alphabets (for example, Arabic-Indic and Devanāgarī digits) along
   with the fullwidth digits "'\uff10'" through "'\uff19'". Case is
   not significant, so, for example, "inf", "Inf", "INFINITY", and
   "iNfINity" are all acceptable spellings for positive infinity.

   If *value* is a "tuple", it should have three components, a sign
   ("0" for positive or "1" for negative), a "tuple" of digits, and an
   integer exponent. For example, "Decimal((0, (1, 4, 1, 4), -3))"
   returns "Decimal('1.414')".

   If *value* is a "float", the binary floating-point value is
   losslessly converted to its exact decimal equivalent.  This
   conversion can often require 53 or more digits of precision.  For
   example, "Decimal(float('1.1'))" converts to
   "Decimal('1.100000000000000088817841970012523233890533447265625')".

   *context* 정밀도는 저장되는 자릿수에 영향을 주지 않습니다. 저장되는
   자릿수는 *value* 의 자릿수만으로 결정됩니다. 예를 들어
   "Decimal('3.00000')" 은 컨텍스트 정밀도가 단지 3이라도 5개의 모든 0
   을 기록합니다.

   The purpose of the *context* argument is determining what to do if
   *value* is a malformed string.  If the context traps
   "InvalidOperation", an exception is raised; otherwise, the
   constructor returns a new Decimal with the value of "NaN".

   일단 만들어지면, "Decimal" 객체는 불변입니다.

   버전 3.2에서 변경: 생성자에 대한 인자는 이제 "float" 인스턴스가 될
   수 있습니다.

   버전 3.3에서 변경: "float" 인자는 "FloatOperation" 트랩이 설정되면
   예외를 발생시킵니다. 기본적으로 트랩은 꺼져 있습니다.

   버전 3.6에서 변경: 코드에서의 정수와 부동 소수점 리터럴과 마찬가지
   로, 밑줄로 무리 지을 수 있습니다.

   Decimal floating-point objects share many properties with the other
   built-in numeric types such as "float" and "int".  All of the usual
   math operations and special methods apply.  Likewise, decimal
   objects can be copied, pickled, printed, used as dictionary keys,
   used as set elements, compared, sorted, and coerced to another type
   (such as "float" or "int").

   Decimal 객체에 대한 산술과 정수 및 실수에 대한 산술에는 약간의 차이
   가 있습니다. Decimal 객체에 나머지 연산자 "%" 가 적용될 때, 결과의
   부호는 제수의 부호가 아닌 *피제수*의 부호가 됩니다:

      >>> (-7) % 4
      1
      >>> Decimal(-7) % Decimal(4)
      Decimal('-3')

   정수 나눗셈 연산자 "//" 의 동작 역시 비슷한 차이를 보입니다. 즉, 가
   장 가까운 정수로 내림하는 대신 실제 몫의 정수 부(0을 향해 자르기)를
   돌려줍니다. 그래서 일반적인 항등식 "x == (x // y) * y + x % y" 를
   유지합니다:

      >>> -7 // 4
      -2
      >>> Decimal(-7) // Decimal(4)
      Decimal('-1')

   "%" 와 "//" 연산자는 명세에 설명된 대로 각각 "remainder" 와
   "divide-integer" 연산을 구현합니다.

   Decimal 객체는 일반적으로 산술 연산에서 float 나
   "fractions.Fraction" 인스턴스와 결합 할 수 없습니다: 예를 들어,
   "float" 에 a "Decimal"을 더하려고 하면 "TypeError" 를 일으킵니다.
   그러나, 파이썬의 비교 연산자를 사용하여 "Decimal" 인스턴스 "x" 와
   다른 숫자 "y" 를 비교할 수 있습니다. 이렇게 해서 서로 다른 형의 숫
   자 간에 동등 비교를 할 때 혼란스러운 결과를 피합니다.

   버전 3.2에서 변경: "Decimal" 인스턴스와 다른 숫자 형 사이의 혼합형
   비교가 이제 완전히 지원됩니다.

   In addition to the standard numeric properties, decimal floating-
   point objects also have a number of specialized methods:

   adjusted()

      최상위 숫자만 남을 때까지 계수의 가장 오른쪽 숫자들을 밀어내도록
      조정된 지수를 반환합니다. "Decimal('321e+5').adjusted()" 는 7을
      반환합니다. 소수점으로부터의 최상위 유효 숫자의 위치를 결정하는
      데 사용됩니다.

   as_integer_ratio()

      주어진 "Decimal" 인스턴스를, 분모가 양수인 기약 분수로 나타내는
      정수의 쌍 "(n, d)" 을 돌려줍니다:

         >>> Decimal('-3.14').as_integer_ratio()
         (-157, 50)

      변환은 정확합니다. 무한대는 OverflowError를, NaN 은 ValueError를
      일으킵니다.

   Added in version 3.6.

   as_tuple()

      숫자의 *네임드 튜플* 표현을 반환합니다: "DecimalTuple(sign,
      digits, exponent)".

   canonical()

      인자의 규범적인 인코딩을 돌려줍니다. 현재 "Decimal" 인스턴스의
      인코딩은 항상 규범적이므로, 이 연산은 인자를 변경하지 않고 반환
      합니다.

   compare(other, context=None)

      두 Decimal 인스턴스의 값을 비교합니다. "compare()" 는 Decimal 인
      스턴스를 반환하고, 피연산자 중 하나가 NaN이면 결과는 NaN입니다:

         a or b is a NaN  ==> Decimal('NaN')
         a < b            ==> Decimal('-1')
         a == b           ==> Decimal('0')
         a > b            ==> Decimal('1')

   compare_signal(other, context=None)

      이 연산은, 모든 NaN 이 신호를 준다는 것을 제외하면 "compare()"
      메서드와 같습니다. 즉, 피연산자가 모두 신호를 주는 NaN이 아니면,
      모든 조용한 NaN 피연산자가 마치 신호를 주는 NaN 인 것처럼 처리됩
      니다.

   compare_total(other, context=None)

      두 개의 피연산자를 숫자 값 대신 추상 표현을 사용하여 비교합니다.
      "compare()" 메서드와 비슷하지만, 결과는 "Decimal" 인스턴스에 대
      해 전 순서(total ordering)를 부여합니다. 같은 숫자 값을 갖지만
      다른 표현의 두 "Decimal" 인스턴스는 이 순서에 의해 다른 것으로
      비교됩니다:

      >>> Decimal('12.0').compare_total(Decimal('12'))
      Decimal('-1')

      조용한 NaN과 신호를 주는 NaN도 전 순서에 포함됩니다. 이 함수의
      결과는, 두 피연산자가 같은 표현을 가질 때 "Decimal('0')", 첫 번
      째 피연산자가 전 순서에서 두 번째 피연산자보다 낮으면
      "Decimal('-1')", 첫 번째 피연산자가 전 순서에서 두 번째 피연산자
      보다 높으면 "Decimal('1')" 입니다. 전 순서에 대한 세부 사항은 명
      세를 참조하십시오.

      이 연산은 컨텍스트의 영향을 받지 않고, 조용합니다: 어떤 플래그도
      변경되지 않고, 어떤 자리 올림도 수행되지 않습니다. 예외적으로,
      두 번째 피연산자를 정확하게 변환할 수 없으면 C 버전은
      InvalidOperation을 발생시킬 수 있습니다.

   compare_total_mag(other, context=None)

      "compare_total()"처럼 두 개의 피연산자를 숫자 값 대신 추상 표현
      을 사용하여 비교하지만, 각 피연산자의 부호를 무시합니다.
      "x.compare_total_mag(y)" 는
      "x.copy_abs().compare_total(y.copy_abs())" 와 동등합니다.

      이 연산은 컨텍스트의 영향을 받지 않고, 조용합니다: 어떤 플래그도
      변경되지 않고, 어떤 자리 올림도 수행되지 않습니다. 예외적으로,
      두 번째 피연산자를 정확하게 변환할 수 없으면 C 버전은
      InvalidOperation을 발생시킬 수 있습니다.

   conjugate()

      그냥 self를 돌려줍니다. 이 메서드는 Decimal 명세를 준수하기 위한
      것뿐입니다.

   copy_abs()

      인자의 절댓값을 반환합니다. 이 연산은 컨텍스트의 영향을 받지 않
      고, 조용합니다: 어떤 플래그도 변경되지 않고, 어떤 자리 올림도 수
      행되지 않습니다.

   copy_negate()

      인자의 음의 부정을 돌려줍니다. 이 연산은 컨텍스트의 영향을 받지
      않고, 조용합니다: 어떤 플래그도 변경되지 않고, 어떤 자리 올림도
      수행되지 않습니다.

   copy_sign(other, context=None)

      두 번째 피연산자의 부호와 같은 부호로 설정된 첫 번째 피연산자의
      복사본을 반환합니다. 예를 들어:

      >>> Decimal('2.3').copy_sign(Decimal('-1.5'))
      Decimal('-2.3')

      이 연산은 컨텍스트의 영향을 받지 않고, 조용합니다: 어떤 플래그도
      변경되지 않고, 어떤 자리 올림도 수행되지 않습니다. 예외적으로,
      두 번째 피연산자를 정확하게 변환할 수 없으면 C 버전은
      InvalidOperation을 발생시킬 수 있습니다.

   exp(context=None)

      주어진 숫자에 대한 (자연) 지수 함수 "e**x" 의 값을 반환합니다.
      결과는 "ROUND_HALF_EVEN" 자리 올림 모드를 사용하여 올바르게 자리
      올림 됩니다.

      >>> Decimal(1).exp()
      Decimal('2.718281828459045235360287471')
      >>> Decimal(321).exp()
      Decimal('2.561702493119680037517373933E+139')

   classmethod from_float(f, /)

      Alternative constructor that only accepts instances of "float"
      or "int".

      Note "Decimal.from_float(0.1)" is not the same as
      "Decimal('0.1')". Since 0.1 is not exactly representable in
      binary floating point, the value is stored as the nearest
      representable value which is "0x1.999999999999ap-4".  That
      equivalent value in decimal is
      "0.1000000000000000055511151231257827021181583404541015625".

      참고:

        파이썬 3.2 이후부터는, "Decimal" 인스턴스를 "float"에서 직접
        생성할 수 있습니다.

         >>> Decimal.from_float(0.1)
         Decimal('0.1000000000000000055511151231257827021181583404541015625')
         >>> Decimal.from_float(float('nan'))
         Decimal('NaN')
         >>> Decimal.from_float(float('inf'))
         Decimal('Infinity')
         >>> Decimal.from_float(float('-inf'))
         Decimal('-Infinity')

      Added in version 3.1.

   fma(other, third, context=None)

      합성된 곱셈-덧셈(fused multiply-add). 중간값 self*other의 자리
      올림 없이 self*other+third를 반환합니다.

      >>> Decimal(2).fma(3, 5)
      Decimal('11')

   is_canonical()

      인자가 규범적이면 "True"를 반환하고, 그렇지 않으면 "False"를 반
      환합니다. 현재 "Decimal" 인스턴스는 항상 규범적이므로 이 연산은
      항상 "True"를 반환합니다.

   is_finite()

      인자가 유한 수이면 "True"를 반환하고, 인자가 무한대나 NaN 이면
      "False"를 반환합니다.

   is_infinite()

      인자가 양이나 음의 무한대면 "True"를 반환하고, 그렇지 않으면
      "False"를 반환합니다.

   is_nan()

      인자가 (조용한 또는 신호를 주는) NaN이면 "True"를 반환하고, 그렇
      지 않으면 "False"를 반환합니다.

   is_normal(context=None)

      인자가 *정상(normal)* 유한 수이면 "True"를 반환합니다. 인자가 0,
      비정상(subnormal), 무한대 또는 NaN 이면 "False"를 반환합니다.

   is_qnan()

      인자가 조용한 NaN이면 "True"를 반환하고, 그렇지 않으면 "False"를
      반환합니다.

   is_signed()

      인자가 음의 부호를 가지면 "True"를 반환하고, 그렇지 않으면
      "False"를 반환합니다. 0과 NaN 모두 부호를 가질 수 있다는 것에 유
      의하세요.

   is_snan()

      인자가 신호를 주는 NaN이면 "True"를 반환하고, 그렇지 않으면
      "False"를 반환합니다.

   is_subnormal(context=None)

      인자가 비정상(subnormal)이면 "True"를 반환하고, 그렇지 않으면
      "False"를 반환합니다.

   is_zero()

      인자가 (양 또는 음의) 0이면 "True"를 반환하고, 그렇지 않으면
      "False"를 반환합니다.

   ln(context=None)

      피연산자의 자연로그(밑 e)를 반환합니다. 결과는 "ROUND_HALF_EVEN"
      자리 올림 모드를 사용하여 올바르게 반올림됩니다.

   log10(context=None)

      피연산자의 상용로그를 반환합니다. 결과는 "ROUND_HALF_EVEN" 자리
      올림 모드를 사용하여 올바르게 반올림됩니다.

   logb(context=None)

      0이 아닌 수의 경우, 피연산자의 조정된 지수를 "Decimal" 인스턴스
      로 반환합니다. 피연산자가 0이면 "Decimal('-Infinity')" 가 반환되
      고 "DivisionByZero" 플래그가 발생합니다. 피연산자가 무한대면
      "Decimal('Infinity')" 가 반환됩니다.

   logical_and(other, context=None)

      "logical_and()" 는 두 개의 *논리적 피연산자*(논리적 피연산자를
      보세요)를 취하는 논리적 연산입니다. 결과는 두 피연산자의 자릿수
      별 "and" 입니다.

   logical_invert(context=None)

      "logical_invert()" 는 논리적 연산입니다. 결과는 피연산자의 자릿
      수별 반전입니다.

   logical_or(other, context=None)

      "logical_or()" 는 두 개의 *논리적 피연산자*(논리적 피연산자를 보
      세요)를 취하는 논리적 연산입니다. 결과는 두 피연산자의 자릿수별
      "or" 입니다.

   logical_xor(other, context=None)

      "logical_xor()"은 두 개의 *논리적 피연산자*(논리적 피연산자를 보
      세요)를 취하는 논리적 연산입니다. 결과는 두 피연산자의 자릿수별
      배타적 or입니다.

   max(other, context=None)

      Like "max(self, other)" except that the context rounding rule is
      applied before returning and that "NaN" values are either
      signaled or ignored (depending on the context and whether they
      are signaling or quiet).

   max_mag(other, context=None)

      "max()"와 비슷하지만, 피연산자의 절댓값을 사용하여 비교가 이루어
      집니다.

   min(other, context=None)

      Like "min(self, other)" except that the context rounding rule is
      applied before returning and that "NaN" values are either
      signaled or ignored (depending on the context and whether they
      are signaling or quiet).

   min_mag(other, context=None)

      "min()"과 비슷하지만, 피연산자의 절댓값을 사용하여 비교가 이루어
      집니다.

   next_minus(context=None)

      주어진 피연산자보다 작고, 주어진 컨텍스트(또는 context가 주어지
      지 않으면 현재 스레드의 컨텍스트)에서 표현 가능한 가장 큰 수를
      돌려줍니다.

   next_plus(context=None)

      주어진 피연산자보다 크고, 주어진 컨텍스트(또는 context가 주어지
      지 않으면 현재 스레드의 컨텍스트)에서 표현 가능한 가장 작은 수를
      돌려줍니다.

   next_toward(other, context=None)

      두 피연산자가 같지 않으면, 두 번째 피연산자의 방향으로 첫 번째
      피연산자에 가장 가까운 숫자를 반환합니다. 두 피연산자가 수치로
      같으면, 첫 번째 피연산자의 복사본을 반환하는데, 부호를 두 번째
      피연산자의 것으로 설정합니다.

   normalize(context=None)

      Used for producing canonical values of an equivalence class
      within either the current context or the specified context.

      This has the same semantics as the unary plus operation, except
      that if the final result is finite it is reduced to its simplest
      form, with all trailing zeros removed and its sign preserved.
      That is, while the coefficient is non-zero and a multiple of ten
      the coefficient is divided by ten and the exponent is
      incremented by 1. Otherwise (the coefficient is zero) the
      exponent is set to 0. In all cases the sign is unchanged.

      For example, "Decimal('32.100')" and "Decimal('0.321000e+2')"
      both normalize to the equivalent value "Decimal('32.1')".

      Note that rounding is applied *before* reducing to simplest
      form.

      In the latest versions of the specification, this operation is
      also known as "reduce".

   number_class(context=None)

      피연산자의 *클래스* 를 설명하는 문자열을 반환합니다. 반환 값은
      다음 10개의 문자열 중 하나입니다.

      * ""-Infinity"", 피연산자가 음의 무한대임을 나타냅니다.

      * ""-Normal"", 피연산자가 음의 정상 수임을 나타냅니다.

      * ""-Subnormal"", 피연산자가 음의 비정상 수임을 나타냅니다.

      * ""-Zero"", 피연산자가 음의 0임을 나타냅니다.

      * ""+Zero"", 피연산자가 양의 0임을 나타냅니다.

      * ""+Subnormal"", 피연산자가 양의 비정상 수임을 나타냅니다.

      * ""+Normal"", 피연산자가 양의 정상 수임을 나타냅니다.

      * ""+Infinity"", 피연산자가 양의 무한대임을 나타냅니다.

      * ""NaN"", 피연산자가 조용한 NaN(Not a Number)임을 나타냅니다.

      * ""sNaN"", 피연산자가 신호를 주는 NaN임을 나타냅니다.

   quantize(exp, rounding=None, context=None)

      자리 올림 후에 첫 번째 피연산자와 같고 두 번째 피연산자의 지수를
      갖는 값을 반환합니다.

      >>> Decimal('1.41421356').quantize(Decimal('1.000'))
      Decimal('1.414')

      다른 연산과 달리, quantize 연산 후의 계수의 길이가 정밀도보다 크
      면, "InvalidOperation" 신호를 줍니다. 이는, 에러 조건이 없으면,
      quantize 된 지수가 항상 오른쪽 피연산자의 지수와 같음을 보장합니
      다.

      또한, 다른 연산과는 달리, 결과가 비정상(subnormal)이고 부정확한
      경우조차도, quantize는 결코 Underflow 신호를 보내지 않습니다.

      두 번째 피연산자의 지수가 첫 번째 피연산자의 지수보다 크면 자리
      올림이 필요할 수 있습니다. 이 경우, 자리 올림 모드는 (주어지면)
      "rounding" 인자에 의해 결정됩니다. 그렇지 않으면 주어진
      "context" 인자에 의해 결정됩니다; 두 인자 모두 주어지지 않으면,
      현재 스레드의 컨텍스트의 자리 올림 모드가 사용됩니다.

      An error is returned whenever the resulting exponent is greater
      than "Emax" or less than "Etiny()".

   radix()

      "Decimal" 클래스가 모든 산술을 수행하는 진수(기수)인
      "Decimal(10)" 을 반환합니다. 명세와의 호환성을 위해 포함됩니다.

   remainder_near(other, context=None)

      *self* 를 *other* 로 나눈 나머지를 반환합니다. 이것은 나머지의
      절댓값을 최소화하기 위해 나머지의 부호가 선택된다는 점에서 "self
      % other" 와 다릅니다. 좀 더 정확히 말하면, 반환 값은 "self - n *
      other" 인데, 여기서 "n" 은 "self / other" 의 정확한 값에 가장 가
      까운 정수이고, 두 개의 정수와의 거리가 같으면 짝수가 선택됩니다.

      결과가 0이면 그 부호는 *self* 의 부호가 됩니다.

      >>> Decimal(18).remainder_near(Decimal(10))
      Decimal('-2')
      >>> Decimal(25).remainder_near(Decimal(10))
      Decimal('5')
      >>> Decimal(35).remainder_near(Decimal(10))
      Decimal('-5')

   rotate(other, context=None)

      첫 번째 피연산자의 계수를 두 번째 피연산자로 지정된 양만큼 회전
      한 결과를 반환합니다. 두 번째 피연산자는 -precision에서
      precision 범위의 정수여야 합니다. 두 번째 피연산자의 절댓값은 회
      전할 자리의 수를 나타냅니다. 두 번째 피연산자가 양수면 왼쪽으로
      회전합니다; 그렇지 않으면 오른쪽으로 회전합니다. 필요하면 정밀도
      에 맞추기 위해 첫 번째 피연산자의 계수에 0이 왼쪽에 채워집니다.
      첫 번째 피연산자의 부호와 지수는 변경되지 않습니다.

   same_quantum(other, context=None)

      Test whether self and other have the same exponent or whether
      both are "NaN".

      이 연산은 컨텍스트의 영향을 받지 않고, 조용합니다: 어떤 플래그도
      변경되지 않고, 어떤 자리 올림도 수행되지 않습니다. 예외적으로,
      두 번째 피연산자를 정확하게 변환할 수 없으면 C 버전은
      InvalidOperation을 발생시킬 수 있습니다.

   scaleb(other, context=None)

      첫 번째 피연산자의 지수를 두 번째 피연산자만큼 조정한 값을 반환
      합니다. 달리 표현하면, 첫 번째 피연산자에 "10**other" 를 곱한 값
      을 반환합니다. 두 번째 피연산자는 정수여야 합니다.

   shift(other, context=None)

      첫 번째 피연산자의 계수를 두 번째 피연산자로 지정된 양만큼 이동
      한 결과를 반환합니다. 두 번째 피연산자는 -precision에서
      precision 범위의 정수여야 합니다. 두 번째 피연산자의 절댓값은 이
      동할 자리의 수를 나타냅니다. 두 번째 피연산자가 양수면 왼쪽으로
      이동합니다; 그렇지 않으면 오른쪽으로 이동합니다. 이동으로 인해
      계수에 들어오는 숫자는 0입니다. 첫 번째 피연산자의 부호와 지수는
      변경되지 않습니다.

   sqrt(context=None)

      인자의 제곱근을 완전한 정밀도로 반환합니다.

   to_eng_string(context=None)

      문자열로 변환합니다. 지수가 필요하면 공학 표기법을 사용합니다.

      공학 표기법의 지수는 3의 배수입니다. 이렇게 하면 소수점 왼쪽에
      최대 3자리를 남기게 되고, 하나나 두 개의 후행 0을 추가해야 할 수
      있습니다.

      예를 들어, 이 메서드는 "Decimal('123E+1')" 을
      "Decimal('1.23E+3')" 으로 변환합니다.

   to_integral(rounding=None, context=None)

      "to_integral_value()" 메서드와 같습니다. "to_integral" 이름은 이
      전 버전과의 호환성을 위해 유지되었습니다.

   to_integral_exact(rounding=None, context=None)

      "Inexact" 나 "Rounded" 신호를 주면서 가장 가까운 정수로 자리 올
      림 합니다. 자리 올림 모드는 (주어지면) "rounding" 매개 변수에 의
      해, 그렇지 않으면 그렇지 않으면 "context" 에 의해 결정됩니다. 두
      매개 변수 모두 지정되지 않으면, 현재 컨텍스트의 자리 올림 모드가
      사용됩니다.

   to_integral_value(rounding=None, context=None)

      "Inexact" 나 "Rounded" 신호를 주지 않고 가장 가까운 정수로 자리
      올림 합니다. 주어지면, *rounding* 을 적용합니다; 그렇지 않으면,
      제공된 *context* 나 현재 컨텍스트의 자리 올림 방법을 사용합니다.

   Decimal numbers can be rounded using the "round()" function:

   round(number)

   round(number, ndigits)

      If *ndigits* is not given or "None", returns the nearest "int"
      to *number*, rounding ties to even, and ignoring the rounding
      mode of the "Decimal" context.  Raises "OverflowError" if
      *number* is an infinity or "ValueError" if it is a (quiet or
      signaling) NaN.

      If *ndigits* is an "int", the context's rounding mode is
      respected and a "Decimal" representing *number* rounded to the
      nearest multiple of "Decimal('1E-ndigits')" is returned; in this
      case, "round(number, ndigits)" is equivalent to
      "self.quantize(Decimal('1E-ndigits'))".  Returns
      "Decimal('NaN')" if *number* is a quiet NaN.  Raises
      "InvalidOperation" if *number* is an infinity, a signaling NaN,
      or if the length of the coefficient after the quantize operation
      would be greater than the current context's precision.  In other
      words, for the non-corner cases:

      * if *ndigits* is positive, return *number* rounded to *ndigits*
        decimal places;

      * if *ndigits* is zero, return *number* rounded to the nearest
        integer;

      * if *ndigits* is negative, return *number* rounded to the
        nearest multiple of "10**abs(ndigits)".

      For example:

         >>> from decimal import Decimal, getcontext, ROUND_DOWN
         >>> getcontext().rounding = ROUND_DOWN
         >>> round(Decimal('3.75'))     # context rounding ignored
         4
         >>> round(Decimal('3.5'))      # round-ties-to-even
         4
         >>> round(Decimal('3.75'), 0)  # uses the context rounding
         Decimal('3')
         >>> round(Decimal('3.75'), 1)
         Decimal('3.7')
         >>> round(Decimal('3.75'), -1)
         Decimal('0E+1')


논리적 피연산자
---------------

The "logical_and()", "logical_invert()", "logical_or()", and
"logical_xor()" methods expect their arguments to be *logical
operands*.  A *logical operand* is a "Decimal" instance whose exponent
and sign are both zero, and whose digits are all either "0" or "1".


Context 객체
============

컨텍스트는 산술 연산을 위한 환경입니다. 정밀도를 제어하고, 자리 올림
규칙을 설정하며, 어떤 신호가 예외로 처리되는지 결정하고, 지수의 범위를
제한합니다.

각 스레드는 자신만의 현재 컨텍스트를 가지는데, "getcontext()" 와
"setcontext()" 함수를 사용하여 액세스하거나 변경합니다:

decimal.getcontext()

   활성 스레드의 현재 컨텍스트를 돌려줍니다.

decimal.setcontext(c, /)

   활성 스레드의 현재 컨텍스트를 *c* 로 설정합니다.

또한 "with" 문과 "localcontext()" 함수를 사용하여 활성 컨텍스트를 일시
적으로 변경할 수 있습니다.

decimal.localcontext(ctx=None, **kwargs)

   Return a context manager that will set the current context for the
   active thread to a copy of *ctx* on entry to the with-statement and
   restore the previous context when exiting the with-statement. If no
   context is specified, a copy of the current context is used.  The
   *kwargs* argument is used to set the attributes of the new context.

   예를 들어, 다음 코드는 현재 십진 정밀도를 42자리로 설정하고, 계산을
   수행한 다음, 이전 컨텍스트를 자동으로 복원합니다:

      from decimal import localcontext

      with localcontext() as ctx:
          ctx.prec = 42   # Perform a high precision calculation
          s = calculate_something()
      s = +s  # Round the final result back to the default precision

   Using keyword arguments, the code would be the following:

      from decimal import localcontext

      with localcontext(prec=42) as ctx:
          s = calculate_something()
      s = +s

   Raises "TypeError" if *kwargs* supplies an attribute that "Context"
   doesn't support.  Raises either "TypeError" or "ValueError" if
   *kwargs* supplies an invalid value for an attribute.

   버전 3.11에서 변경: "localcontext()" now supports setting context
   attributes through the use of keyword arguments.

아래에 설명된 "Context" 생성자를 사용하여 새로운 컨텍스트를 만들 수도
있습니다. 또한, 이 모듈은 세 가지 미리 만들어진 컨텍스트를 제공합니다:

decimal.BasicContext

   이것은 일반 십진 산술 명세에서 정의된 표준 컨텍스트입니다. 정밀도는
   9로 설정됩니다. 자리 올림은 "ROUND_HALF_UP"으로 설정됩니다. 모든 플
   래그가 지워집니다. 모든 트랩은 "Inexact", "Rounded", "Subnormal"을
   제외하고는 활성화됩니다 (예외로 처리됩니다).

   많은 트랩이 활성화되었으므로, 이 컨텍스트는 디버깅에 유용합니다.

decimal.ExtendedContext

   이것은 일반 십진 산술 명세에서 정의된 표준 컨텍스트입니다. 정밀도는
   9로 설정됩니다. 자리 올림은 "ROUND_HALF_EVEN"으로 설정됩니다. 모든
   플래그가 지워집니다. 아무 트랩도 활성화되지 않습니다 (그래서 계산
   중에 예외가 발생하지 않습니다).

   Because the traps are disabled, this context is useful for
   applications that prefer to have result value of "NaN" or
   "Infinity" instead of raising exceptions.  This allows an
   application to complete a run in the presence of conditions that
   would otherwise halt the program.

decimal.DefaultContext

   이 컨텍스트는 새로운 컨텍스트의 프로토타입으로 "Context" 생성자에
   의해 사용됩니다. 필드(가령 정밀도)를 변경하면 "Context" 생성자에 의
   해 생성된 새로운 컨텍스트에 대한 기본값을 변경하는 효과가 있습니다.

   이 컨텍스트는 다중 스레드 환경에서 가장 유용합니다. 스레드가 시작되
   기 전에 필드 중 하나를 변경하면 시스템 전체의 기본값을 설정하는 효
   과가 있습니다. 스레드가 시작된 후에 필드를 변경하는 것은. 스레드 동
   기화를 통해 경쟁 조건을 방지해야 하므로 권장되지 않습니다.

   단일 스레드 환경에서는, 이 컨텍스트를 아예 사용하지 않는 것이 좋습
   니다. 대신, 아래에 설명된 대로 명시적으로 컨텍스트를 만드십시오.

   The default values are "Context.prec"="28",
   "Context.rounding"="ROUND_HALF_EVEN", and enabled traps for
   "Overflow", "InvalidOperation", and "DivisionByZero".

3개의 제공된 컨텍스트 외에도, 새로운 컨텍스트를 "Context" 생성자를 사
용하여 만들 수 있습니다.

class decimal.Context(prec=None, rounding=None, Emin=None, Emax=None, capitals=None, clamp=None, flags=None, traps=None)

   새로운 컨텍스트를 만듭니다. 필드가 지정되지 않았거나 "None" 이면,
   기본값은 "DefaultContext" 에서 복사됩니다. *flags* 필드가 지정되지
   않았거나 "None" 이면, 모든 플래그가 지워집니다.

   prec

      An integer in the range ["1", "MAX_PREC"] that sets the
      precision for arithmetic operations in the context.

   rounding

      One of the constants listed in the section Rounding Modes.

   traps
   flags

      Lists of any signals to be set. Generally, new contexts should
      only set traps and leave the flags clear.

   Emin
   Emax

      Integers specifying the outer limits allowable for exponents.
      *Emin* must be in the range ["MIN_EMIN", "0"], *Emax* in the
      range ["0", "MAX_EMAX"].

   capitals

      Either "0" or "1" (the default). If set to "1", exponents are
      printed with a capital "E"; otherwise, a lowercase "e" is used:
      "Decimal('6.02e+23')".

   clamp

      Either "0" (the default) or "1".  If set to "1", the exponent
      "e" of a "Decimal" instance representable in this context is
      strictly limited to the range "Emin - prec + 1 <= e <= Emax -
      prec + 1". If *clamp* is "0" then a weaker condition holds: the
      adjusted exponent of the "Decimal" instance is at most "Emax".
      When *clamp* is "1", a large normal number will, where possible,
      have its exponent reduced and a corresponding number of zeros
      added to its coefficient, in order to fit the exponent
      constraints; this preserves the value of the number but loses
      information about significant trailing zeros.  For example:

         >>> Context(prec=6, Emax=999, clamp=1).create_decimal('1.23e999')
         Decimal('1.23000E+999')

      A *clamp* value of "1" allows compatibility with the fixed-width
      decimal interchange formats specified in IEEE 754.

   The "Context" class defines several general purpose methods as well
   as a large number of methods for doing arithmetic directly in a
   given context. In addition, for each of the "Decimal" methods
   described above (with the exception of the "adjusted()" and
   "as_tuple()" methods) there is a corresponding "Context" method.
   For example, for a "Context" instance "C" and "Decimal" instance
   "x", "C.exp(x)" is equivalent to "x.exp(context=C)".  Each
   "Context" method accepts a Python integer (an instance of "int")
   anywhere that a Decimal instance is accepted.

   clear_flags()

      Resets all of the flags to "0".

   clear_traps()

      Resets all of the traps to "0".

      Added in version 3.3.

   copy()

      컨텍스트의 복사본을 돌려줍니다.

   copy_decimal(num, /)

      Decimal 인스턴스 num의 복사본을 반환합니다.

   create_decimal(num='0', /)

      *self* 를 컨텍스트로 사용해서, *num* 으로 새 Decimal 인스턴스를
      만듭니다. "Decimal" 생성자와 달리, 컨텍스트 정밀도, 자리 올림 방
      법, 플래그 및 트랩이 변환에 적용됩니다.

      이는 상수가 보통 응용 프로그램에 필요한 것보다 더 큰 정밀도로 제
      공되기 때문에 유용합니다. 또 다른 이점은 자리 올림이 현재 정밀도
      를 초과하는 자릿수로 인한 의도하지 않은 결과를 즉시 제거한다는
      것입니다. 다음 예제에서, 자리 올림 되지 않은 입력을 사용한다는
      것은 합계에 0을 추가하면 결과가 달라질 수 있음을 의미합니다.:

         >>> getcontext().prec = 3
         >>> Decimal('3.4445') + Decimal('1.0023')
         Decimal('4.45')
         >>> Decimal('3.4445') + Decimal(0) + Decimal('1.0023')
         Decimal('4.44')

      이 메서드는 IBM 명세의 to-number 연산을 구현합니다. 인자가 문자
      열이면, 선행 또는 후행 공백이나 밑줄이 허용되지 않습니다.

   create_decimal_from_float(f, /)

      float *f* 로 새 Decimal 인스턴스를 만들지만, *self* 를 컨텍스트
      로 사용하여 자리 올림 합니다. "Decimal.from_float()" 클래스 메서
      드와는 달리, 컨텍스트 정밀도, 자리 올림 방법, 플래그 및 트랩이
      변환에 적용됩니다.

         >>> context = Context(prec=5, rounding=ROUND_DOWN)
         >>> context.create_decimal_from_float(math.pi)
         Decimal('3.1415')
         >>> context = Context(prec=5, traps=[Inexact])
         >>> context.create_decimal_from_float(math.pi)
         Traceback (most recent call last):
             ...
         decimal.Inexact: None

      Added in version 3.1.

   Etiny()

      비정상 결과에 대한 최소 지수 값인 "Emin - prec + 1" 과 같은 값을
      반환합니다. 언더 플로우가 발생하면, 지수는 "Etiny" 로 설정됩니다
      .

   Etop()

      "Emax - prec + 1" 과 같은 값을 반환합니다.

   십진수로 작업하는 일반적인 접근법은 "Decimal" 인스턴스를 생성한 다
   음 활성 스레드의 현재 컨텍스트 내에서 진행되는 산술 연산을 적용하는
   것입니다. 다른 방법은 특정 컨텍스트 내에서 계산하기 위해 컨텍스트
   메서드를 사용하는 것입니다. 메서드는 "Decimal" 클래스의 메서드와 비
   슷하며 여기에서는 간단히 설명합니다.

   abs(x, /)

      *x* 의 절댓값을 돌려줍니다.

   add(x, y, /)

      *x* 와 *y* 의 합을 돌려줍니다.

   canonical(x, /)

      같은 Decimal 객체 *x* 를 반환합니다.

   compare(x, y, /)

      *x* 와 *y* 를 수치로 비교합니다.

   compare_signal(x, y, /)

      두 피연산자의 값을 수치로 비교합니다.

   compare_total(x, y, /)

      추상 표현을 사용하여 두 피연산자를 비교합니다.

   compare_total_mag(x, y, /)

      부호를 무시하고, 추상 표현을 사용하여 두 피연산자를 비교합니다.

   copy_abs(x, /)

      부호가 0으로 설정되어있는 *x* 의 복사본을 돌려줍니다.

   copy_negate(x, /)

      부호가 반전된 *x* 복사본을 반환합니다.

   copy_sign(x, y, /)

      *y* 에서 *x* 로 부호를 복사합니다.

   divide(x, y, /)

      *x* 를 *y* 로 나눈 값을 반환합니다.

   divide_int(x, y, /)

      *x* 를 *y* 로 나눈 후 정수로 잘라낸 값을 반환합니다.

   divmod(x, y, /)

      두 숫자를 나누고 결과의 정수 부분을 반환합니다.

   exp(x, /)

      Returns "e ** x".

   fma(x, y, z, /)

      *x* 에 *y* 를 곱한 후 *z* 를 더한 값을 반환합니다.

   is_canonical(x, /)

      *x* 가 규범적일 경우 "True"를 반환합니다; 그렇지 않으면 "False"
      를 반환합니다.

   is_finite(x, /)

      *x* 가 유한이면 "True"를 반환합니다; 그렇지 않으면 "False"를 반
      환합니다.

   is_infinite(x, /)

      *x* 가 무한대면 "True"를 반환합니다; 그렇지 않으면 "False"를 반
      환합니다.

   is_nan(x, /)

      *x* 가 qNaN 이나 sNaN 이면 "True"를 반환합니다; 그렇지 않으면
      "False"를 반환합니다.

   is_normal(x, /)

      *x* 가 정상 수면 "True"를 반환합니다; 그렇지 않으면 "False"를 반
      환합니다.

   is_qnan(x, /)

      *x* 가 조용한 NaN이면 "True"를 반환합니다; 그렇지 않으면 "False"
      를 반환합니다.

   is_signed(x, /)

      *x* 가 음수면 "True"를 반환합니다; 그렇지 않으면 "False"를 반환
      합니다.

   is_snan(x, /)

      *x* 가 신호를 주는 NaN 이면 "True"를 반환합니다; 그렇지 않으면
      "False"를 반환합니다.

   is_subnormal(x, /)

      *x* 가 비정상이면 "True"를 반환합니다; 그렇지 않으면 "False"를
      반환합니다.

   is_zero(x, /)

      *x* 가 0이면 "True"를 반환합니다; 그렇지 않으면 "False"를 반환합
      니다.

   ln(x, /)

      *x* 의 자연로그(밑 e)를 반환합니다.

   log10(x, /)

      *x* 의 상용로그를 반환합니다.

   logb(x, /)

      피연산자의 최상위 유효 숫자의 크기의 지수를 반환합니다.

   logical_and(x, y, /)

      각 피연산자의 자릿수별로 논리적 연산 *and* 를 적용합니다.

   logical_invert(x, /)

      *x* 의 모든 자릿수를 반전합니다.

   logical_or(x, y, /)

      각 피연산자의 자릿수별로 논리적 연산 *or* 를 적용합니다.

   logical_xor(x, y, /)

      각 피연산자의 자릿수별로 논리적 연산 *xor* 를 적용합니다.

   max(x, y, /)

      두 값을 수치로 비교해, 최댓값을 돌려줍니다.

   max_mag(x, y, /)

      부호를 무시하고 값을 수치로 비교합니다.

   min(x, y, /)

      두 값을 수치로 비교해, 최솟값을 돌려줍니다.

   min_mag(x, y, /)

      부호를 무시하고 값을 수치로 비교합니다.

   minus(x, /)

      minus는 파이썬에서 단항 접두사 빼기 연산자에 해당합니다.

   multiply(x, y, /)

      *x* 와 *y* 의 곱을 반환합니다.

   next_minus(x, /)

      *x* 보다 작고 표현 가능한 가장 큰 수를 반환합니다.

   next_plus(x, /)

      *x* 보다 크고 표현 가능한 가장 작은 수를 반환합니다.

   next_toward(x, y, /)

      *y* 방향으로 *x* 에 가장 가까운 숫자를 반환합니다.

   normalize(x, /)

      *x* 를 가장 간단한 형태로 환원합니다.

   number_class(x, /)

      *x* 의 클래스를 가리키는 문자열을 돌려줍니다.

   plus(x, /)

      plus는 파이썬에서 단항 접두사 더하기 연산자에 해당합니다. 이 연
      산은 컨텍스트 정밀도와 자리 올림을 적용하므로 항등 연산이 *아닙
      니다*.

   power(x, y, modulo=None)

      "x" 의 "y" 거듭제곱을 돌려줍니다. 주어지면 "modulo" 모듈로로 환
      원합니다.

      With two arguments, compute "x**y".  If "x" is negative then "y"
      must be integral.  The result will be inexact unless "y" is
      integral and the result is finite and can be expressed exactly
      in 'precision' digits. The rounding mode of the context is used.
      Results are always correctly rounded in the Python version.

      "Decimal(0) ** Decimal(0)"은 "InvalidOperation"이 되며,
      "InvalidOperation"가 트랩 되지 않으면, "Decimal('NaN')"이 됩니다
      .

      버전 3.3에서 변경: The C module computes "power()" in terms of
      the correctly rounded "exp()" and "ln()" functions. The result
      is well-defined but only "almost always correctly rounded".

      세 인자로는 "(x**y) % modulo" 를 계산합니다. 세 인자 형식의 경우
      , 인자에 다음과 같은 제한이 있습니다:

      * 세 인자는 모두 정수여야 합니다.

      * "y" 는 음수가 아니어야 합니다.

      * "x" 나 "y" 중 적어도 하나는 0이 아니어야 합니다

      * "modulo" 는 0이 아니고 최대 'precision' 자릿수를 가져야 합니다

      "Context.power(x, y, modulo)" 의 결괏값은 무한 정밀도로 "(x**y)
      % modulo" 를 계산할 때 얻을 수 있는 값과 같지만, 더 효율적으로
      계산됩니다. 결과의 지수는 "x", "y" 및 "modulo" 의 지수와 관계없
      이 0입니다. 결과는 항상 정확합니다.

   quantize(x, y, /)

      *y* 의 지수를 가지는 (자리 올림 된) *x* 와 같은 값을 반환합니다.

   radix()

      Decimal이기 때문에 단지 10을 반환합니다, :)

   remainder(x, y, /)

      정수 나눗셈의 나머지를 반환합니다.

      결과가 0이 아닐 때, 결과의 부호는 원래의 피제수와 같습니다.

   remainder_near(x, y, /)

      "x - y * n" 을 반환하는데, *n* 은 "x / y" 의 정확한 값에 가장 가
      까운 정수입니다 (결과가 0이면 그 부호는 *x* 의 부호가 됩니다).

   rotate(x, y, /)

      *x* 를 *y* 번 회전한 복사본을 반환합니다.

   same_quantum(x, y, /)

      두 피연산자의 지수가 같으면 "True"를 반환합니다.

   scaleb(x, y, /)

      첫 번째 피연산자의 지수에 두 번째 값을 더해서 반환합니다.

   shift(x, y, /)

      *x* 를 *y* 번 이동한 복사본을 반환합니다.

   sqrt(x, /)

      음이 아닌 수의 제곱근을 컨텍스트의 정밀도로 반환합니다.

   subtract(x, y, /)

      *x* 와 *y* 의 차를 돌려줍니다.

   to_eng_string(x, /)

      문자열로 변환합니다. 지수가 필요하면 공학 표기법을 사용합니다.

      공학 표기법의 지수는 3의 배수입니다. 이렇게 하면 소수점 왼쪽에
      최대 3자리를 남기게 되고, 하나나 두 개의 후행 0을 추가해야 할 수
      있습니다.

   to_integral_exact(x, /)

      정수로 자리 올림 합니다.

   to_sci_string(x, /)

      과학 표기법을 사용하여 숫자를 문자열로 변환합니다.


상수
====

이 절의 상수는 C 모듈에서만 의미가 있습니다. 호환성을 위해 순수 파이썬
버전에도 포함되어 있습니다.

+-----------------------+-----------------------+---------------------------------+
|                       | 32-비트               | 64-비트                         |
|=======================|=======================|=================================|
| decimal.MAX_PREC      | "425000000"           | "999999999999999999"            |
+-----------------------+-----------------------+---------------------------------+
| decimal.MAX_EMAX      | "425000000"           | "999999999999999999"            |
+-----------------------+-----------------------+---------------------------------+
| decimal.MIN_EMIN      | "-425000000"          | "-999999999999999999"           |
+-----------------------+-----------------------+---------------------------------+
| decimal.MIN_ETINY     | "-849999999"          | "-1999999999999999997"          |
+-----------------------+-----------------------+---------------------------------+

decimal.HAVE_THREADS

   값은 "True"입니다. 이제 파이썬에는 항상 스레드가 있기 때문에, 폐지
   되었습니다.

   버전 3.9부터 폐지됨.

decimal.HAVE_CONTEXTVAR

   The default value is "True". If Python is "configured using the
   --without-decimal-contextvar option", the C version uses a thread-
   local rather than a coroutine-local context and the value is
   "False".  This is slightly faster in some nested context scenarios.

   Added in version 3.8.3.


자리 올림 모드
==============

decimal.ROUND_CEILING

   Round towards "Infinity".

decimal.ROUND_DOWN

   0을 향해 자리 올림 합니다.

decimal.ROUND_FLOOR

   Round towards "-Infinity".

decimal.ROUND_HALF_DOWN

   가장 가까운 값으로 반올림하고, 동률이면 0에서 가까운 것을 선택합니
   다.

decimal.ROUND_HALF_EVEN

   가장 가까운 값으로 반올림하고, 동률이면 짝수를 선택합니다.

decimal.ROUND_HALF_UP

   가장 가까운 값으로 반올림하고, 동률이면 0에서 먼 것을 선택합니다.

decimal.ROUND_UP

   0에서 먼 쪽으로 자리 올림 합니다.

decimal.ROUND_05UP

   0을 향해 자리 올림 했을 때 마지막 숫자가 0이나 5면 0에서 먼 쪽으로
   자리 올림 합니다. 그렇지 않으면 0을 향해 자리 올림 합니다.


신호
====

신호는 계산 중 발생하는 조건을 나타냅니다. 각각은 하나의 컨텍스트 플래
그와 하나의 컨텍스트 트랩 활성화기에 대응합니다.

컨텍스트 플래그는 조건이 발생할 때마다 설정됩니다. 계산 후에, 플래그는
정보를 얻기 위한 목적으로 확인될 수 있습니다 (예를 들어, 계산이 정확한
지를 판별하기 위해). 플래그를 확인한 후 다음 계산을 시작하기 전에 모든
플래그를 지우십시오.

컨텍스트의 트랩 활성화기가 신호에 대해 설정되면, 조건은 파이썬 예외를
일으킵니다. 예를 들어, "DivisionByZero" 트랩이 설정되면, 이 조건을 만
날 때 "DivisionByZero" 예외가 발생합니다.

class decimal.Clamped

   표현 제약 조건에 맞도록 지수를 변경했습니다.

   Typically, clamping occurs when an exponent falls outside the
   context's "Emin" and "Emax" limits.  If possible, the exponent is
   reduced to fit by adding zeros to the coefficient.

class decimal.DecimalException

   다른 신호의 베이스 클래스이고 "ArithmeticError" 의 서브 클래스입니
   다.

class decimal.DivisionByZero

   무한대가 아닌 숫자를 0으로 나눴다는 신호를 줍니다.

   Can occur with division, modulo division, or when raising a number
   to a negative power.  If this signal is not trapped, returns
   "Infinity" or "-Infinity" with the sign determined by the inputs to
   the calculation.

class decimal.Inexact

   자리 올림이 발생했고 결과가 정확하지 않음을 나타냅니다.

   자리 올림 도중 0이 아닌 숫자가 삭제된 경우 신호를 줍니다. 자리 올림
   된 결과가 반환됩니다. 신호 플래그나 트랩은 결과가 정확하지 않을 때
   를 감지하는 데 사용됩니다.

class decimal.InvalidOperation

   유효하지 않은 연산이 수행되었습니다.

   Indicates that an operation was requested that does not make sense.
   If not trapped, returns "NaN".  Possible causes include:

      Infinity - Infinity
      0 * Infinity
      Infinity / Infinity
      x % 0
      Infinity % x
      sqrt(-x) and x > 0
      0 ** 0
      x ** (non-integer)
      x ** Infinity

class decimal.Overflow

   수치적 오버플로.

   Indicates the exponent is larger than "Context.Emax" after rounding
   has occurred.  If not trapped, the result depends on the rounding
   mode, either pulling inward to the largest representable finite
   number or rounding outward to "Infinity".  In either case,
   "Inexact" and "Rounded" are also signaled.

class decimal.Rounded

   정보가 손실되지는 않았지만 자리 올림이 발생했습니다.

   Signaled whenever rounding discards digits; even if those digits
   are zero (such as rounding "5.00" to "5.0").  If not trapped,
   returns the result unchanged.  This signal is used to detect loss
   of significant digits.

class decimal.Subnormal

   Exponent was lower than "Emin" prior to rounding.

   연산 결과가 비정상(지수가 너무 작음)일 때 발생합니다. 트랩 되지 않
   으면, 결과를 그대로 반환합니다.

class decimal.Underflow

   결과가 0으로 자리 올림 되는 수치적 언더플로.

   자리 올림에 의해 비정상 결과가 0으로 밀릴 때 발생합니다. "Inexact"
   와 "Subnormal" 신호도 줍니다.

class decimal.FloatOperation

   float와 Decimal을 혼합하는 데 더 엄격한 의미를 사용합니다.

   신호가 트랩되지 않으면 (기본값), "Decimal" 생성자,
   "create_decimal()" 및 모든 비교 연산자에서 float와 Decimal을 혼합
   할 수 있습니다. 변환과 비교 모두 정확합니다. 복합 연산의 발생은 컨
   텍스트 플래그에 "FloatOperation" 을 설정하여 조용히 기록됩니다.
   "from_float()" 나 "create_decimal_from_float()" 를 사용한 명시적 변
   환은 플래그를 설정하지 않습니다.

   그렇지 않으면 (신호가 트랩되면), 같음 비교와 명시적 변환만 조용히
   수행됩니다. 다른 모든 혼합된 연산은 "FloatOperation" 을 발생시킵니
   다.

다음 표는 신호의 계층 구조를 요약한 것입니다:

   exceptions.ArithmeticError(exceptions.Exception)
       DecimalException
           Clamped
           DivisionByZero(DecimalException, exceptions.ZeroDivisionError)
           Inexact
               Overflow(Inexact, Rounded)
               Underflow(Inexact, Rounded, Subnormal)
           InvalidOperation
           Rounded
           Subnormal
           FloatOperation(DecimalException, exceptions.TypeError)


Floating-point notes
====================


증가시킨 정밀도로 자리 올림 오차 줄이기
---------------------------------------

The use of decimal floating point eliminates decimal representation
error (making it possible to represent "0.1" exactly); however, some
operations can still incur round-off error when non-zero digits exceed
the fixed precision.

The effects of round-off error can be amplified by the addition or
subtraction of nearly offsetting quantities resulting in loss of
significance.  Knuth provides two instructive examples where rounded
floating-point arithmetic with insufficient precision causes the
breakdown of the associative and distributive properties of addition:

   # Examples from Seminumerical Algorithms, Section 4.2.2.
   >>> from decimal import Decimal, getcontext
   >>> getcontext().prec = 8

   >>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
   >>> (u + v) + w
   Decimal('9.5111111')
   >>> u + (v + w)
   Decimal('10')

   >>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
   >>> (u*v) + (u*w)
   Decimal('0.01')
   >>> u * (v+w)
   Decimal('0.0060000')

"decimal" 모듈은 유효숫자의 손실을 피할 수 있을 만큼 정밀도를 확장함으
로써 항등 관계를 복구할 수 있게 합니다 :

   >>> getcontext().prec = 20
   >>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
   >>> (u + v) + w
   Decimal('9.51111111')
   >>> u + (v + w)
   Decimal('9.51111111')
   >>>
   >>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
   >>> (u*v) + (u*w)
   Decimal('0.0060000')
   >>> u * (v+w)
   Decimal('0.0060000')


특수 값
-------

The number system for the "decimal" module provides special values
including "NaN", "sNaN", "-Infinity", "Infinity", and two zeros, "+0"
and "-0".

무한대는 다음과 같이 직접 생성될 수 있습니다: "Decimal('Infinity')".
또한, "DivisionByZero" 신호가 트랩 되지 않을 때 0으로 나눠서 발생할 수
있습니다. 마찬가지로, "Overflow" 신호가 트랩 되지 않을 때, 무한대는 표
현 가능한 가장 큰 수의 한계를 넘어서 자리 올림 된 결과가 될 수 있습니
다.

무한대는 부호가 있고 (아핀) 산술 연산에 사용될 수 있는데, 매우 크고 불
확정적(indeterminate)인 숫자로 취급됩니다. 예를 들어, 무한대에 상수를
더하면 또 다른 무한대를 줍니다.

Some operations are indeterminate and return "NaN", or if the
"InvalidOperation" signal is trapped, raise an exception.  For
example, "0/0" returns "NaN" which means "not a number".  This variety
of "NaN" is quiet and, once created, will flow through other
computations always resulting in another "NaN".  This behavior can be
useful for a series of computations that occasionally have missing
inputs --- it allows the calculation to proceed while flagging
specific results as invalid.

A variant is "sNaN" which signals rather than remaining quiet after
every operation.  This is a useful return value when an invalid result
needs to interrupt a calculation for special handling.

The behavior of Python's comparison operators can be a little
surprising where a "NaN" is involved.  A test for equality where one
of the operands is a quiet or signaling "NaN" always returns "False"
(even when doing "Decimal('NaN')==Decimal('NaN')"), while a test for
inequality always returns "True".  An attempt to compare two Decimals
using any of the "<", "<=", ">" or ">=" operators will raise the
"InvalidOperation" signal if either operand is a "NaN", and return
"False" if this signal is not trapped.  Note that the General Decimal
Arithmetic specification does not specify the behavior of direct
comparisons; these rules for comparisons involving a "NaN" were taken
from the IEEE 854 standard (see Table 3 in section 5.7).  To ensure
strict standards-compliance, use the "compare()" and
"compare_signal()" methods instead.

부호 있는 0은 언더플로 하는 계산의 결과일 수 있습니다. 계산을 더 정밀
하게 수행한다면 얻게 될 결과의 기호를 유지합니다. 크기가 0이기 때문에,
양과 음의 0은 같다고 취급되며 부호는 정보 용입니다.

In addition to the two signed zeros which are distinct yet equal,
there are various representations of zero with differing precisions
yet equivalent in value.  This takes a bit of getting used to.  For an
eye accustomed to normalized floating-point representations, it is not
immediately obvious that the following calculation returns a value
equal to zero:

>>> 1 / Decimal('Infinity')
Decimal('0E-1000026')


스레드로 작업하기
=================

"getcontext()" 함수는 스레드마다 다른 "Context" 객체에 접근합니다. 별
도의 스레드 컨텍스트를 갖는다는 것은 스레드가 다른 스레드를 방해하지
않고 변경할 수 있음을 의미합니다 (가령 "getcontext().prec=10").

마찬가지로, "setcontext()" 함수는 자동으로 대상을 현재 스레드에 할당합
니다.

"setcontext()" 가 "getcontext()" 전에 호출되지 않았다면,
"getcontext()" 는 현재 스레드에서 사용할 새로운 컨텍스트를 자동으로 생
성합니다.

새 컨텍스트는 *DefaultContext* 라는 프로토타입 컨텍스트에서 복사됩니다
. 각 스레드가 응용 프로그램 전체에서 같은 값을 사용하도록 기본값을 제
어하려면, *DefaultContext* 객체를 직접 수정하십시오. "getcontext()" 를
호출하는 스레드 사이에 경쟁 조건이 없도록, 어떤 스레드가 시작되기 *전
에* 수행되어야 합니다. 예를 들면:

   # Set applicationwide defaults for all threads about to be launched
   DefaultContext.prec = 12
   DefaultContext.rounding = ROUND_DOWN
   DefaultContext.traps = ExtendedContext.traps.copy()
   DefaultContext.traps[InvalidOperation] = 1
   setcontext(DefaultContext)

   # Afterwards, the threads can be started
   t1.start()
   t2.start()
   t3.start()
    . . .


조리법
======

다음은 유틸리티 함수로 사용되고 "Decimal" 클래스로 작업하는 방법을 보
여주는 몇 가지 조리법입니다:

   def moneyfmt(value, places=2, curr='', sep=',', dp='.',
                pos='', neg='-', trailneg=''):
       """Convert Decimal to a money formatted string.

       places:  required number of places after the decimal point
       curr:    optional currency symbol before the sign (may be blank)
       sep:     optional grouping separator (comma, period, space, or blank)
       dp:      decimal point indicator (comma or period)
                only specify as blank when places is zero
       pos:     optional sign for positive numbers: '+', space or blank
       neg:     optional sign for negative numbers: '-', '(', space or blank
       trailneg:optional trailing minus indicator:  '-', ')', space or blank

       >>> d = Decimal('-1234567.8901')
       >>> moneyfmt(d, curr='$')
       '-$1,234,567.89'
       >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-')
       '1.234.568-'
       >>> moneyfmt(d, curr='$', neg='(', trailneg=')')
       '($1,234,567.89)'
       >>> moneyfmt(Decimal(123456789), sep=' ')
       '123 456 789.00'
       >>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>')
       '<0.02>'

       """
       q = Decimal(10) ** -places      # 2 places --> '0.01'
       sign, digits, exp = value.quantize(q).as_tuple()
       result = []
       digits = list(map(str, digits))
       build, next = result.append, digits.pop
       if sign:
           build(trailneg)
       for i in range(places):
           build(next() if digits else '0')
       if places:
           build(dp)
       if not digits:
           build('0')
       i = 0
       while digits:
           build(next())
           i += 1
           if i == 3 and digits:
               i = 0
               build(sep)
       build(curr)
       build(neg if sign else pos)
       return ''.join(reversed(result))

   def pi():
       """Compute Pi to the current precision.

       >>> print(pi())
       3.141592653589793238462643383

       """
       getcontext().prec += 2  # extra digits for intermediate steps
       three = Decimal(3)      # substitute "three=3.0" for regular floats
       lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
       while s != lasts:
           lasts = s
           n, na = n+na, na+8
           d, da = d+da, da+32
           t = (t * n) / d
           s += t
       getcontext().prec -= 2
       return +s               # unary plus applies the new precision

   def exp(x):
       """Return e raised to the power of x.  Result type matches input type.

       >>> print(exp(Decimal(1)))
       2.718281828459045235360287471
       >>> print(exp(Decimal(2)))
       7.389056098930650227230427461
       >>> print(exp(2.0))
       7.38905609893
       >>> print(exp(2+0j))
       (7.38905609893+0j)

       """
       getcontext().prec += 2
       i, lasts, s, fact, num = 0, 0, 1, 1, 1
       while s != lasts:
           lasts = s
           i += 1
           fact *= i
           num *= x
           s += num / fact
       getcontext().prec -= 2
       return +s

   def cos(x):
       """Return the cosine of x as measured in radians.

       The Taylor series approximation works best for a small value of x.
       For larger values, first compute x = x % (2 * pi).

       >>> print(cos(Decimal('0.5')))
       0.8775825618903727161162815826
       >>> print(cos(0.5))
       0.87758256189
       >>> print(cos(0.5+0j))
       (0.87758256189+0j)

       """
       getcontext().prec += 2
       i, lasts, s, fact, num, sign = 0, 0, 1, 1, 1, 1
       while s != lasts:
           lasts = s
           i += 2
           fact *= i * (i-1)
           num *= x * x
           sign *= -1
           s += num / fact * sign
       getcontext().prec -= 2
       return +s

   def sin(x):
       """Return the sine of x as measured in radians.

       The Taylor series approximation works best for a small value of x.
       For larger values, first compute x = x % (2 * pi).

       >>> print(sin(Decimal('0.5')))
       0.4794255386042030002732879352
       >>> print(sin(0.5))
       0.479425538604
       >>> print(sin(0.5+0j))
       (0.479425538604+0j)

       """
       getcontext().prec += 2
       i, lasts, s, fact, num, sign = 1, 0, x, 1, x, 1
       while s != lasts:
           lasts = s
           i += 2
           fact *= i * (i-1)
           num *= x * x
           sign *= -1
           s += num / fact * sign
       getcontext().prec -= 2
       return +s


Decimal FAQ
===========

Q. "decimal.Decimal('1234.5')" 라고 입력하는 것은 귀찮은 일입니다. 대
화형 인터프리터를 사용할 때 타자를 최소화할 방법이 있습니까?

A. 일부 사용자는 생성자를 하나의 문자로 축약합니다:

>>> D = decimal.Decimal
>>> D('1.23') + D('3.45')
Decimal('4.68')

Q. 소수점 두 자리의 고정 소수점 응용 프로그램에서, 일부 입력에 여러 자
리가 있고 자리 올림 해야 합니다. 어떤 것은 여분의 자릿수가 없다고 가정
되지만, 유효성 검사가 필요합니다. 어떤 방법을 사용해야 합니까?

A. The "quantize()" method rounds to a fixed number of decimal places.
If the "Inexact" trap is set, it is also useful for validation:

>>> TWOPLACES = Decimal(10) ** -2       # same as Decimal('0.01')

>>> # Round to two places
>>> Decimal('3.214').quantize(TWOPLACES)
Decimal('3.21')

>>> # Validate that a number does not exceed two places
>>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Decimal('3.21')

>>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Traceback (most recent call last):
   ...
Inexact: None

Q. 일단 유효한 두 자리 입력이 있으면, 응용 프로그램 전체에서 해당 불변
성을 어떻게 유지합니까?

A. Some operations like addition, subtraction, and multiplication by
an integer will automatically preserve fixed point.  Others
operations, like division and non-integer multiplication, will change
the number of decimal places and need to be followed-up with a
"quantize()" step:

>>> a = Decimal('102.72')           # Initial fixed-point values
>>> b = Decimal('3.17')
>>> a + b                           # Addition preserves fixed-point
Decimal('105.89')
>>> a - b
Decimal('99.55')
>>> a * 42                          # So does integer multiplication
Decimal('4314.24')
>>> (a * b).quantize(TWOPLACES)     # Must quantize non-integer multiplication
Decimal('325.62')
>>> (b / a).quantize(TWOPLACES)     # And quantize division
Decimal('0.03')

In developing fixed-point applications, it is convenient to define
functions to handle the "quantize()" step:

>>> def mul(x, y, fp=TWOPLACES):
...     return (x * y).quantize(fp)
...
>>> def div(x, y, fp=TWOPLACES):
...     return (x / y).quantize(fp)

>>> mul(a, b)                       # Automatically preserve fixed-point
Decimal('325.62')
>>> div(b, a)
Decimal('0.03')

Q. There are many ways to express the same value.  The numbers "200",
"200.000", "2E2", and ".02E+4" all have the same value at various
precisions. Is there a way to transform them to a single recognizable
canonical value?

A. The "normalize()" method maps all equivalent values to a single
representative:

>>> values = map(Decimal, '200 200.000 2E2 .02E+4'.split())
>>> [v.normalize() for v in values]
[Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2')]

Q. When does rounding occur in a computation?

A. It occurs *after* the computation.  The philosophy of the decimal
specification is that numbers are considered exact and are created
independent of the current context.  They can even have greater
precision than current context.  Computations process with those exact
inputs and then rounding (or other context operations) is applied to
the *result* of the computation:

   >>> getcontext().prec = 5
   >>> pi = Decimal('3.1415926535')   # More than 5 digits
   >>> pi                             # All digits are retained
   Decimal('3.1415926535')
   >>> pi + 0                         # Rounded after an addition
   Decimal('3.1416')
   >>> pi - Decimal('0.00005')        # Subtract unrounded numbers, then round
   Decimal('3.1415')
   >>> pi + 0 - Decimal('0.00005').   # Intermediate values are rounded
   Decimal('3.1416')

Q. 일부 십진수 값은 항상 지수 표기법으로 인쇄됩니다. 지수가 아닌 표현
을 얻을 방법이 있습니까?

A. For some values, exponential notation is the only way to express
the number of significant places in the coefficient.  For example,
expressing "5.0E+3" as "5000" keeps the value constant but cannot show
the original's two-place significance.

응용 프로그램이 유효 숫자를 추적하는 데 신경 쓰지 않으면, 지수 및 후행
0을 제거하고 유효숫자를 잃지만, 값이 바뀌지 않도록 하기는 쉽습니다:

>>> def remove_exponent(d):
...     return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()

>>> remove_exponent(Decimal('5E+3'))
Decimal('5000')

Q. 일반 float를 "Decimal"로 변환하는 방법이 있습니까?

A. Yes, any binary floating-point number can be exactly expressed as a
Decimal though an exact conversion may take more precision than
intuition would suggest:

   >>> Decimal(math.pi)
   Decimal('3.141592653589793115997963468544185161590576171875')

Q. 복잡한 계산에서, 정밀도가 부족하거나 자리 올림 이상이 발생하여 엉터
리 결과를 얻지는 않았는지 확인하려면 어떻게 해야 합니까?

A. decimal 모듈은 결과를 쉽게 테스트할 수 있게 합니다. 가장 좋은 방법
은 더 높은 정밀도와 다양한 자리 올림 모드를 사용하여 계산을 다시 실행
하는 것입니다. 크게 다른 결과는 정밀도 부족, 자리 올림 모드 문제, 부적
절한 입력 또는 수치가 불안정한 알고리즘을 나타냅니다.

컨텍스트 정밀도가 입력이 아닌 연산 결과에 적용된다는 사실을 확인했습니
다. 다른 정밀도의 값을 혼합할 때 주의해야 할 것이 있습니까?

A. 그렇습니다. 원칙은 모든 값이 정확한 것으로 간주하므로 해당 값에 대
한 산술도 마찬가지라는 것입니다. 결과 만 자리 올림 됩니다. 입력에 대한
이점은 "입력하는 것이 얻는 것"이라는 것입니다. 단점은 입력값을 자리 올
림 하는 것을 잊어버리면 결과가 이상하게 보일 수 있다는 점입니다:

   >>> getcontext().prec = 3
   >>> Decimal('3.104') + Decimal('2.104')
   Decimal('5.21')
   >>> Decimal('3.104') + Decimal('0.000') + Decimal('2.104')
   Decimal('5.20')

해법은 정밀도를 높이거나 단항 플러스 연산을 사용하여 입력의 자리 올림
을 강제 수행하는 것입니다:

   >>> getcontext().prec = 3
   >>> +Decimal('1.23456789')      # unary plus triggers rounding
   Decimal('1.23')

다른 방법으로, 입력은 "Context.create_decimal()" 메서드를 사용하여 생
성 시에 자리 올림 될 수 있습니다:

>>> Context(prec=5, rounding=ROUND_DOWN).create_decimal('1.2345678')
Decimal('1.2345')

Q. CPython 구현은 커다란 수에서 빠릅니까?

A. Yes.  In the CPython and PyPy3 implementations, the C/CFFI versions
of the decimal module integrate the high speed libmpdec library for
arbitrary precision correctly rounded decimal floating-point
arithmetic [1]. "libmpdec" uses Karatsuba multiplication for medium-
sized numbers and the Number Theoretic Transform for very large
numbers.

The context must be adapted for exact arbitrary precision arithmetic.
"Emin" and "Emax" should always be set to the maximum values, "clamp"
should always be 0 (the default).  Setting "prec" requires some care.

The easiest approach for trying out bignum arithmetic is to use the
maximum value for "prec" as well [2]:

   >>> setcontext(Context(prec=MAX_PREC, Emax=MAX_EMAX, Emin=MIN_EMIN))
   >>> x = Decimal(2) ** 256
   >>> x / 128
   Decimal('904625697166532776746648320380374280103671755200316906558262375061821325312')

For inexact results, "MAX_PREC" is far too large on 64-bit platforms
and the available memory will be insufficient:

   >>> Decimal(1) / 3
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   MemoryError

On systems with overallocation (e.g. Linux), a more sophisticated
approach is to adjust "prec" to the amount of available RAM.  Suppose
that you have 8GB of RAM and expect 10 simultaneous operands using a
maximum of 500MB each:

   >>> import sys
   >>>
   >>> # Maximum number of digits for a single operand using 500MB in 8-byte words
   >>> # with 19 digits per word (4-byte and 9 digits for the 32-bit build):
   >>> maxdigits = 19 * ((500 * 1024**2) // 8)
   >>>
   >>> # Check that this works:
   >>> c = Context(prec=maxdigits, Emax=MAX_EMAX, Emin=MIN_EMIN)
   >>> c.traps[Inexact] = True
   >>> setcontext(c)
   >>>
   >>> # Fill the available precision with nines:
   >>> x = Decimal(0).logical_invert() * 9
   >>> sys.getsizeof(x)
   524288112
   >>> x + 2
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
     decimal.Inexact: [<class 'decimal.Inexact'>]

일반적으로 (그리고 특히 초과 할당이 없는 시스템에서), 더 엄격한 경계를
추정하고 모든 계산이 정확할 것으로 예상되면 "Inexact" 트랩을 설정하는
것이 좋습니다.

[1] Added in version 3.3.

[2] 버전 3.9에서 변경: 이 접근법은 정수가 아닌 거듭제곱을 제외한 모든
    정확한 결과에 적용됩니다.
