9.4. "decimal" --- 10進固定及び浮動小数点数の算術演算
*****************************************************

バージョン 2.4 で追加.

"decimal" モジュールは10進の浮動小数点算術をサポートします。 "decimal"
には、 "float" データ型に比べて、以下のような利点があります:

* Decimal 「は人々を念頭にデザインされた浮動小数点モデルを元にしてお
  り 、必然的に最も重要な指針があります -- コンピュータは人々が学校で
  習っ た算術と同じように動作する算術を提供しなければならない」 -- 10
  進数演 算仕様より。

* 10進数を正確に表現できます。 "1.1" や "2.2" のような数は、2 進数の
  浮 動小数点型では正しく表現できません。エンドユーザは普通、 2 進数に
  お ける "1.1 + 2.2" の近似値が "3.3000000000000003" だからといって、
  そ のように表示してほしいとは考えないものです。

* 値の正確さは算術にも及びます。10進の浮動小数点による計算では、
  "0.1 + 0.1 + 0.1 - 0.3" は厳密にゼロに等しくなります。 2 進浮動小数
  点では "5.5511151231257827e-017" になってしまいます。ゼロに近い値と
  はいえ、 この誤差は数値間の等価性テストの信頼性を阻害します。また、
  誤差が蓄積 されることもあります。こうした理由から、数値間の等価性を
  厳しく保たな ければならないようなアプリケーションを考えるなら、10進
  数による数値表 現が望ましいということになります。

* "decimal" モジュールでは、有効桁数の表記が取り入れられており、例え
  ば "1.30 + 1.20" は "2.50" になります。すなわち、末尾のゼロは有効数
  字を 示すために残されます。こうした仕様は通貨計算を行うアプリケーシ
  ョンで は慣例です。乗算の場合、「教科書的な」アプローチでは、乗算の
  被演算子 すべての桁数を使います。例えば、 "1.3 * 1.2" は "1.56" にな
  り、 "1.30 * 1.20" は "1.5600" になります。

* ハードウェアによる 2 進浮動小数点表現と違い、"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')

* 2進と10進の浮動小数点は、いずれも広く公開されている標準仕様のもと
  に 実装されています。組み込みの浮動小数点型では、標準仕様で提唱され
  てい る機能のほんのささやかな部分を利用できるにすぎませんが、
  "decimal" で は標準仕様が要求している全ての機能を利用できます。必要
  に応じて、プロ グラマは値の丸めやシグナル処理を完全に制御できます。
  この中には全ての 不正確な操作を例外でブロックして正確な算術を遵守さ
  せるオプションもあ ります。

* decimal モジュールは「偏見なく、正確な丸めなしの十進算術(固定小数
  点 算術と呼ばれることもある)と丸めありの浮動小数点数算術」(10進数演
  算仕 様より引用)をサポートするようにデザインされました。

このモジュールは、10進数型、算術コンテキスト (context for arithmetic)
、そしてシグナル (signal) という三つの概念を中心に設計されています。

10進数型は変更不可能な型です。これは符号、係数部、そして指数を持ちます
。有効桁数を残すために、仮数部の末尾にあるゼロは切り詰められません。
"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" があります。

シグナルとは、演算の過程で生じる例外的条件です。個々のシグナルは、アプ
リケーションそれぞれの要求に従って、無視されたり、単なる情報とみなされ
たり、例外として扱われたりします。 "decimal" モジュールには、
"Clamped", "InvalidOperation", "DivisionByZero", "Inexact", "Rounded",
"Subnormal", "Overflow", "Underflow" といったシグナルがあります。

各シグナルには、フラグとトラップイネーブラがあります。演算上何らかのシ
グナルに遭遇すると、フラグは 1 にセットされます。このとき、もしトラッ
プイネーブラが 1 にセットされていれば、例外を送出します。フラグの値は
膠着型 (sticky) なので、演算によるフラグの変化をモニタしたければ、予め
フラグをリセットしておかなければなりません。

参考:

  * IBM による汎用10進演算仕様、 The General Decimal Arithmetic
    Specification 。


9.4.1. クイックスタートチュートリアル
=====================================

普通、 "decimal" を使うときには、モジュールを import し、現在の演算コ
ンテキストを "getcontext()" で調べ、必要なら、精度、丸め、有効なトラッ
プを設定します:

   >>> from decimal import *
   >>> getcontext()
   Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
           capitals=1, flags=[], traps=[Overflow, DivisionByZero,
           InvalidOperation])

   >>> getcontext().prec = 7       # Set a new precision

"Decimal" インスタンスは、整数、文字列、浮動小数点数、またはタプルから
構成できます。整数や浮動小数点数からの構成は、整数や浮動小数点数の値を
正確に変換します。 "Decimal" は "数値ではない (Not a Number)" を表す
"NaN" や正負の "Infinity" (無限大)、 "-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.41421356237')
>>> Decimal(2) ** Decimal('0.5')
Decimal('1.414213562373095048801688724')
>>> Decimal('NaN')
Decimal('NaN')
>>> Decimal('-Infinity')
Decimal('-Infinity')

新たな "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')

decimal はほとんどの場面で Python の他の機能とうまくやりとりできます。
decimal 浮動小数点小劇場 (flying circus) をお見せしましょう:

   >>> data = 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)     # round() first converts to binary floating point
   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')

"quantize()" メソッドは位を固定して数値を丸めます。このメソッドは、結
果を固定の桁数で丸めることがよくある、金融アプリケーションで便利です:

>>> 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=-999999999, Emax=999999999,
           capitals=1, 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

演算コンテキストには、演算中に遭遇した例外的状況をモニタするためのシグ
ナルフラグがあります。フラグが一度セットされると、明示的にクリアするま
で残り続けます。そのため、フラグのモニタを行いたいような演算の前には
"clear_flags()" メソッドでフラグをクリアしておくのがベストです。

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

*flags* エントリから、 "Pi" の有理数による近似値が丸められた (コンテキ
スト内で決められた精度を超えた桁数が捨てられた) ことと、計算結果が厳密
でない (無視された桁の値に非ゼロのものがあった) ことがわかります。

コンテキストの "traps" フィールドに入っている辞書を使うと、個々のトラ
ップをセットできます:

   >>> 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" オブジェクトを生成できたら、ほとんどのプログラムは他の
Python 数値型と全く変わらないかのように "Decimal" を操作できます。


9.4.2. Decimal オブジェクト
===========================

class decimal.Decimal([value[, context]])

   *value* に基づいて新たな "Decimal" オブジェクトを構築します。

   *value* は整数、文字列、タプル、 "float" および他の "Decimal" オブ
   ジェクトにできます。 *value* を指定しない場合、 "Decimal('0')" を返
   します。 *value* が文字列の場合、先頭と末尾の空白を取り除いた後には
   以下の 10進数文字列の文法に従わなければなりません:

      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

   *value* を Unicode 文字列にした場合、他の Unicode 数字も上の
   "digit" の場所に使うことができます。つまり各書記体系における (アラ
   ビア-インド系やデーヴァナーガリーなど) の数字や、全角数字０
   ("u'\uff10'") から９ ("u'\uff19'") までなどです。

   *value* を "tuple" にする場合、タプルは三つの要素を持ち、それぞれ符
   号 (正なら "0" 、負なら "1")、仮数部を表す数字の "tuple" 、そして指
   数を表す整数でなければなりません。例えば、 "Decimal((0, (1, 4, 1,
   4), -3))" は "Decimal('1.414')" を返します。

   *value* を "float" にする場合、2進浮動小数点数値が損失なく正確に等
   価な Decimal に変換されます。この変換はしばしば 53 桁以上の精度を要
   求します。例えば、 "Decimal(float('1.1'))" は
   "Decimal('1.100000000000000088817841970012523233890533447265625')"
   に変換されます。

   *context* の精度 (precision) は、記憶される桁数には影響しません。桁
   数は *value* に指定した桁数だけから決定されます。例えば、演算コンテ
   キストに指定された精度が 3 桁しかなくても、"Decimal('3.00000')" は
   5 つのゼロを全て記憶します。

   *context* 引数の目的は、 *value* が正しくない形式の文字列であった場
   合に行う処理を決めることにあります; 演算コンテキストが
   "InvalidOperation" をトラップするようになっていれば、例外を送出しま
   す。それ以外の場合には、コンストラクタは値が "NaN" の "Decimal" を
   返します。

   一度生成すると、 "Decimal" オブジェクトは変更不能 (immutable) にな
   ります。

   バージョン 2.6 で変更: 文字列から Decimal インスタンスを生成する際
   に先頭と末尾の空白が許されることになりました。

   バージョン 2.7 で変更: コンストラクタに対する引数に "float" インス
   タンスも許されるようになりました。

   10進浮動小数点オブジェクトは、 "float" や "int" のような他の組み込
   み型と多くの点で似ています。通常の数学演算や特殊メソッドを適用でき
   ます。また、 "Decimal" オブジェクトはコピーでき、pickle 化でき、
   print で出力でき、辞書のキーにでき、集合の要素にでき、比較、保存、
   他の型 ("float" や "long") への型強制を行えます。

   10進オブジェクトの算術演算と整数や浮動小数点数の算術演算には少々違
   いがあります。10進オブジェクトに対して剰余演算を適用すると、計算結
   果の符号は除数の符号ではなく *被除数* の符号と一致します:

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

   演算子 "%" と演算子 "//" は (それぞれ) 仕様にあるような "剰余" 操作
   と "整数除算" 操作を実装しています。

   Decimal オブジェクトは一般に、算術演算で浮動小数点数と組み合わせる
   ことができません。例えば、 "Decimal" に "float" を足そうとすると、
   "TypeError" が送出されます。ただしこの規則には例外があります。
   "float" インスタンス "x" と "Decimal" インスタンス "y" を比較する比
   較演算子です。この例外がなかったとすると、 "Decimal" と "float" イ
   ンスタンスの比較は、リファレンスマニュアルの 式 (expression) 節で記
   述されている、異なる型のオブジェクトを比較するときの一般の規則に従
   うことになり、紛らわしい結果につながります。

   バージョン 2.7 で変更: "float" インスタンス "x" と "Decimal" インス
   タンス "y" の比較は、 "x" と "y" の値に基づく結果を返すようになりま
   した。以前のバージョンでは、どんな "float" インスタンス "x" とどん
   な "Decimal" インスタンス "y" に対しても、 "x < y" は同じ (任意の)
   結果を返していました。

   こうした標準的な数値型の特性の他に、10進浮動小数点オブジェクトには
   様々な特殊メソッドがあります:

   adjusted()

      仮数の先頭の一桁だけが残るように右側の数字を追い出す桁シフトを行
      い、その結果の指数部を返します: "Decimal('321e+5').adjusted()"
      は 7 を返します。最上桁の小数点からの相対位置を調べる際に使いま
      す。

   as_tuple()

      数値を表現するための名前付きタプル(*named tuple*):
      "DecimalTuple(sign, digittuple, exponent)" を返します。

      バージョン 2.6 で変更: 名前付きタプル (named tuple) を使うように
      なりました。

   canonical()

      引数の標準的(canonical)エンコーディングを返します。現在のところ
      、 "Decimal" インスタンスのエンコーディングは常に標準的なので、
      この操作は引数に手を加えずに返します。

      バージョン 2.6 で追加.

   compare(other[, context])

      二つの Decimal インスタンスの値を比較します。この演算は普通の比
      較メソッド "__cmp__()" と同じように振舞いますが、 "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])

      この演算は "compare()" とほとんど同じですが、全ての NaN がシグナ
      ルを送るところが異なります。すなわち、どちらの比較対象も発信
      (signaling) NaN でないならば無言 (quiet) NaN である比較対象があ
      たかも発信 NaN であるかのように扱われます。

      バージョン 2.6 で追加.

   compare_total(other)

      二つの対象を数値によらず抽象表現によって比較します。 "compare()"
      に似ていますが、結果は "Decimal" に全順序を与えます。この順序づ
      けによると、数値的に等しくても異なった表現を持つ二つの "Decimal"
      インスタンスの比較は等しくなりません:

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

      無言 NaN と発信 NaN もこの全順序に位置付けられます。この関数の結
      果は、もし比較対象が同じ表現を持つならば "Decimal('0')" であり、
      一つめの比較対象が二つめより下位にあれば "Decimal('-1')"、上位に
      あれば "Decimal('1')" です。全順序の詳細については仕様を参照して
      ください。

      バージョン 2.6 で追加.

   compare_total_mag(other)

      二つの対象を "compare_total()" のように数値によらず抽象表現によ
      って比較しますが、両者の符号を無視します。
      "x.compare_total_mag(y)" は
      "x.copy_abs().compare_total(y.copy_abs())" と等価です。

      バージョン 2.6 で追加.

   conjugate()

      self を返すだけです。このメソッドは十進演算仕様に適合するためだ
      けのものです。

      バージョン 2.6 で追加.

   copy_abs()

      引数の絶対値を返します。この演算はコンテキストに影響されず、静か
      です。すなわち、フラグは変更されず、丸めは行われません。

      バージョン 2.6 で追加.

   copy_negate()

      引数の符号を変えて返します。この演算はコンテキストに影響されず、
      静かです。すなわち、フラグは変更されず、丸めは行われません。

      バージョン 2.6 で追加.

   copy_sign(other)

      最初の演算対象のコピーに二つめと同じ符号を付けて返します。たとえ
      ば:

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

      この演算はコンテキストに影響されず、静かです。すなわち、フラグは
      変更されず、丸めは行われません。

      バージョン 2.6 で追加.

   exp([context])

      与えられた数での(自然)指数関数 "e**x" の値を返します。結果は
      "ROUND_HALF_EVEN" 丸めモードで正しく丸められます。

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

      バージョン 2.6 で追加.

   from_float(f)

      浮動小数点数を正確に小数に変換するクラスメソッドです。

      なお、*Decimal.from_float(0.1)* は *Decimal('0.1')* と同じではあ
      りません。0.1 は二進浮動小数点数で正確に表せないので、その値は表
      現できる最も近い値、*0x1.999999999999ap-4* として記憶されます。
      浮動小数点数での等価な値は
      *0.1000000000000000055511151231257827021181583404541015625* です
      。

      注釈: Python 2.7 以降では、 "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')

      バージョン 2.7 で追加.

   fma(other, third[, context])

      融合積和(fused multiply-add)です。self*other+third を途中結果の
      積 self*other で丸めを行わずに計算して返します。

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

      バージョン 2.6 で追加.

   is_canonical()

      引数が標準的(canonical)ならば "True" を返し、そうでなければ
      "False" を返します。現在のところ、 "Decimal" のインスタンスは常
      に標準的なのでこのメソッドの結果はいつでも "True" です。

      バージョン 2.6 で追加.

   is_finite()

      引数が有限の数値ならば "True" を、無限大か NaN ならば "False" を
      返します。

      バージョン 2.6 で追加.

   is_infinite()

      引数が正または負の無限大ならば "True" を、そうでなければ "False"
      を返します。

      バージョン 2.6 で追加.

   is_nan()

      引数が (無言か発信かは問わず) NaN であれば "True" を、そうでなけ
      れば "False" を返します。

      バージョン 2.6 で追加.

   is_normal()

      引数が *正規(normal)* のゼロでない有限数値で調整された指数が
      *Emin* 以上ならば "True" を返します。引数がゼロ、非正規
      (subnormal)、無限大または NaN であれば "False" を返します。ここ
      での *正規* という用語は標準的な(canonical)値を作り出すために使
      われる "normalize()" メソッドにおける意味合いとは異なりますので
      注意して下さい。

      バージョン 2.6 で追加.

   is_qnan()

      引数が無言 NaN であれば "True" を、そうでなければ "False" を返し
      ます。

      バージョン 2.6 で追加.

   is_signed()

      引数に負の符号がついていれば "True" を、そうでなければ "False"
      を返します。注意すべきはゼロや NaN なども符号を持ち得ることです
      。

      バージョン 2.6 で追加.

   is_snan()

      引数が発信 NaN であれば "True" を、そうでなければ "False" を返し
      ます。

      バージョン 2.6 で追加.

   is_subnormal()

      引数が非正規数(subnormal)であれば "True" を、そうでなければ
      "False" を返します。非正規な数値とは、ゼロでなく、有限で、調整さ
      れた指数が *Emin* 未満のものを指します。

      バージョン 2.6 で追加.

   is_zero()

      引数が(正または負の)ゼロであれば "True" を、そうでなければ
      "False" を返します。

      バージョン 2.6 で追加.

   ln([context])

      演算対象の自然対数(底 e の対数)を返します。結果は
      "ROUND_HALF_EVEN" 丸めモードで正しく丸められます。

      バージョン 2.6 で追加.

   log10([context])

      演算対象の底 10 の対数を返します。結果は "ROUND_HALF_EVEN" 丸め
      モードで正しく丸められます。

      バージョン 2.6 で追加.

   logb([context])

      非零の数値については、 "Decimal" インスタンスとして調整された指
      数を返します。演算対象がゼロだった場合、 "Decimal('-Infinity')"
      が返され "DivisionByZero" フラグが送出されます。演算対象が無限大
      だった場合、 "Decimal('Infinity')" が返されます。

      バージョン 2.6 で追加.

   logical_and(other[, context])

      "logical_and()" は二つの *論理引数* (論理引数 参照)を取る論理演
      算です。結果は二つの引数の数字ごとの "and" です。

      バージョン 2.6 で追加.

   logical_invert([context])

      "logical_invert()" は論理演算です。結果は引数の数字ごとの反転で
      す。

      バージョン 2.6 で追加.

   logical_or(other[, context])

      "logical_or()" は二つの *論理引数* (論理引数 参照)を取る論理演算
      です。結果は二つの引数の数字ごとの "or" です。

      バージョン 2.6 で追加.

   logical_xor(other[, context])

      "logical_xor()" は二つの *論理引数* (論理引数 参照)を取る論理演
      算です。結果は二つの引数の数字ごとの排他的論理和です。

      バージョン 2.6 で追加.

   max(other[, context])

      "max(self, other)" と同じですが、値を返す前に現在のコンテキスト
      に即した丸め規則を適用します。また、 "NaN" に対して、(コンテキス
      トの設定と、発信か無言どちらのタイプであるかに応じて) シグナルを
      発行するか無視します。

   max_mag(other[, context])

      "max()" メソッドに似ていますが、比較は絶対値で行われます。

      バージョン 2.6 で追加.

   min(other[, context])

      "min(self, other)" と同じですが、値を返す前に現在のコンテキスト
      に即した丸め規則を適用します。また、 "NaN" に対して、(コンテキス
      トの設定と、発信か無言どちらのタイプであるかに応じて) シグナルを
      発行するか無視します。

   min_mag(other[, context])

      "min()" メソッドに似ていますが、比較は絶対値で行われます。

      バージョン 2.6 で追加.

   next_minus([context])

      与えられたコンテキスト(またはコンテキストが渡されなければ現スレ
      ッドのコンテキスト)において表現可能な、操作対象より小さい最大の
      数を返します。

      バージョン 2.6 で追加.

   next_plus([context])

      与えられたコンテキスト(またはコンテキストが渡されなければ現スレ
      ッドのコンテキスト)において表現可能な、操作対象より大きい最小の
      数を返します。

      バージョン 2.6 で追加.

   next_toward(other[, context])

      二つの比較対象が等しくなければ、一つめの対象に最も近く二つめの対
      象へ近付く方向の数を返します。もし両者が数値的に等しければ、二つ
      めの対象の符号を採った一つめの対象のコピーを返します。

      バージョン 2.6 で追加.

   normalize([context])

      数値を正規化 (normalize) して、右端に連続しているゼロを除去し、
      "Decimal('0')" と同じ結果はすべて "Decimal('0e0')" に変換します
      。等価クラスの属性から基準表現を生成する際に用います。たとえば、
      "Decimal('32.100')" と "Decimal('0.321000e+2')" の正規化は、いず
      れも同じ値 "Decimal('32.1')" になります。

   number_class([context])

      操作対象の *クラス* を表す文字列を返します。返されるのは以下の10
      種類のいずれかです。

      * ""-Infinity"", 負の無限大であることを示します。

      * ""-Normal"", 負の通常数であることを示します。

      * ""-Subnormal"", 負の非正規数であることを示します。

      * ""-Zero"", 負のゼロであることを示します。

      * ""+Zero"", 正のゼロであることを示します。

      * ""+Subnormal"", 正の非正規数であることを示します。

      * ""+Normal"", 正の通常数であることを示します。

      * ""+Infinity"", 正の無限大であることを示します。

      * ""NaN"", 無言 (quiet) NaN (Not a Number) であることを示しま
        す 。

      * ""sNaN"", 発信(signaling) NaN であることを示します。

      バージョン 2.6 で追加.

   quantize(exp[, rounding[, context[, watchexp]]])

      二つめの操作対象と同じ指数を持つように丸めを行った、一つめの操作
      対象と等しい値を返します。

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

      他の操作と違い、打ち切り(quantize)操作後の係数の長さが精度を越え
      た場合には、 "InvalidOperation" がシグナルされます。これによりエ
      ラー条件がない限り打ち切られた指数が常に右側の引数と同じになるこ
      とが保証されます。

      同様に、他の操作と違い、quantize は Underflow を、たとえ結果が非
      正規になったり不正確になったとしても、シグナルしません。

      二つ目の演算対象の指数が一つ目のそれよりも大きければ丸めが必要か
      もしれません。この場合、丸めモードは以下のように決められます。
      "rounding" 引数が与えられていればそれが使われます。そうでなけれ
      ば "context" 引数で決まります。どちらの引数も渡されなければ現在
      のスレッドのコンテキストの丸めモードが使われます。

      *watchexp* が設定されている場合(デフォルト)、処理結果の指数が
      "Emax" よりも大きい場合や "Etiny" よりも小さい場合にエラーを返し
      ます。

   radix()

      "Decimal(10)" つまり "Decimal" クラスがその全ての算術を実行する
      基数を返します。仕様との互換性のために取り入れられています。

      バージョン 2.6 で追加.

   remainder_near(other[, context])

      *self* を *other* で割った剰余を返します。これは "self % other"
      とは違って、剰余の絶対値を小さくするように符号が選ばれます。より
      詳しく言うと、"n" を "self / other" の正確な値に最も近い整数とし
      たときの "self - n * other" が返り値になります。最も近い整数が2
      つある場合には偶数のものが選ばれます。

      結果が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])

      一つめの演算対象の数字を二つめので指定された量だけ巡回(rotate)し
      た結果を返します。二つめの演算対象は -precision から precision
      までの範囲の整数でなければなりません。この二つめの演算対象の絶対
      値が何桁ずらすかを決めます。そしてもし正の数ならば巡回の方向は左
      に、そうでなければ右になります。一つめの演算対象の仮数部は必要な
      らば精度いっぱいまでゼロで埋められます。符号と指数は変えられませ
      ん。

      バージョン 2.6 で追加.

   same_quantum(other[, context])

      *self* と *other* が同じ指数を持っているか、あるいは双方とも
      "NaN" である場合に真を返します。

   scaleb(other[, context])

      二つめの演算対象で調整された指数の一つめの演算対象を返します。同
      じことですが、一つめの演算対象を "10**other" 倍したものを返しま
      す。二つめの演算対象は整数でなければなりません。

      バージョン 2.6 で追加.

   shift(other[, context])

      一つめの演算対象の数字を二つめので指定された量だけシフトした結果
      を返します。二つめの演算対象は -precision から precision までの
      範囲の整数でなければなりません。この二つめの演算対象の絶対値が何
      桁ずらすかを決めます。そしてもし正の数ならばシフトの方向は左に、
      そうでなければ右になります。一つめの演算対象の係数は必要ならば精
      度いっぱいまでゼロで埋められます。符号と指数は変えられません。

      バージョン 2.6 で追加.

   sqrt([context])

      平方根を精度いっぱいまで求めます。

   to_eng_string([context])

      文字列に変換します。指数が必要なら工学表記が使われます。

      工学表記法では指数は 3 の倍数になります。これにより、基数の小数
      部には最大で 3 桁までの数字が残されるとともに、末尾に 1 つまたは
      2 つの 0 の付加が必要とされるかもしれません。

      たとえば、"Decimal('123E+1')" は "Decimal('1.23E+3')" に変換され
      ます。

   to_integral([rounding[, context]])

      "to_integral_value()" メソッドと同じです。"to_integral" の名前は
      古いバージョンとの互換性のために残されています。

   to_integral_exact([rounding[, context]])

      最近傍の整数に値を丸め、丸めが起こった場合には "Inexact" または
      "Rounded" のシグナルを適切に出します。丸めモードは以下のように決
      められます。 "rounding" 引数が与えられていればそれが使われます。
      そうでなければ "context" 引数で決まります。どちらの引数も渡され
      なければ現在のスレッドのコンテキストの丸めモードが使われます。

      バージョン 2.6 で追加.

   to_integral_value([rounding[, context]])

      "Inexact" や "Rounded" といったシグナルを出さずに最近傍の整数に
      値を丸めます。 *rounding* が指定されていれば適用されます; それ以
      外の場合、値丸めの方法は *context* の設定か現在のコンテキストの
      設定になります。

      バージョン 2.6 で変更: "to_integral" から "to_integral_value" に
      改名されました。古い名前も互換性のために残されています。


9.4.2.1. 論理引数
-----------------

"logical_and()", "logical_invert()", "logical_or()", および
"logical_xor()" メソッドはその引数が *論理引数* であると想定しています
。 *論理引数* とは "Decimal" インスタンスで指数と符号は共にゼロであり
、各桁の数字が "0" か "1" であるものです。


9.4.3. Context オブジェクト
===========================

コンテキスト (context) とは、算術演算における環境設定です。コンテキス
トは計算精度を決定し、値丸めの方法を設定し、シグナルのどれが例外になる
かを決め、指数の範囲を制限しています。

多重スレッドで処理を行う場合には各スレッドごとに現在のコンテキストがあ
り、 "getcontext()" や "setcontext()" といった関数でアクセスしたり設定
変更できます:

decimal.getcontext()

   アクティブなスレッドの現在のコンテキストを返します。

decimal.setcontext(c)

   アクティブなスレッドのコンテキストを *c* に設定します。

Python 2.5 から、 "with" 文と "localcontext()" 関数を使って実行するコ
ンテキストを一時的に変更することもできるようになりました。

decimal.localcontext([c])

   with 文の入口でアクティブなスレッドのコンテキストを *c* のコピーに
   設定し、with 文を抜ける時に元のコンテキストに復旧する、コンテキスト
   マネージャを返します。コンテキストが指定されなければ、現在のコンテ
   キストのコピーが使われます。

   バージョン 2.5 で追加.

   たとえば、以下のコードでは精度を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

      with localcontext(BasicContext):      # temporarily use the BasicContext
          print Decimal(1) / Decimal(7)
          print Decimal(355) / Decimal(113)

新たなコンテキストは、以下で説明する "Context" コンストラクタを使って
生成できます。その他にも、 "decimal" モジュールでは作成済みのコンテキ
ストを提供しています:

class decimal.BasicContext

   汎用10進演算仕様で定義されている標準コンテキストの一つです。精度は
   9 桁に設定されています。丸め規則は "ROUND_HALF_UP" です。すべての演
   算結果フラグはクリアされています。 "Inexact", "Rounded",
   "Subnormal" を除く全ての演算エラートラップが有効 (例外として扱う)
   になっています。

   多くのトラップが有効になっているので、デバッグの際に便利なコンテキ
   ストです。

class decimal.ExtendedContext

   汎用10進演算仕様で定義されている標準コンテキストの一つです。精度は
   9 桁に設定されています。丸め規則は "ROUND_HALF_EVEN" です。すべての
   演算結果フラグはクリアされています。トラップは全て無効(演算中に一切
   例外を送出しない) になっています。

   トラップが無効になっているので、エラーの伴う演算結果を "NaN" や
   "Infinity" にし、例外を送出しないようにしたいアプリケーションに向い
   たコンテキストです。このコンテキストを使うと、他の場合にはプログラ
   ムが停止してしまうような状況があっても実行を完了させられます。

class decimal.DefaultContext

   "Context" コンストラクタが新たなコンテキストを作成するさいに雛形に
   するコンテキストです。このコンテキストのフィールド (精度の設定など)
   を変更すると、 "Context" コンストラクタが生成する新たなコンテキスト
   に影響を及ぼします。

   このコンテキストは、主に多重スレッド環境で便利です。スレッドを開始
   する前に何らかのフィールドを変更しておくと、システム全体のデフォル
   ト設定に効果を及ぼすことができます。スレッドを開始した後にフィール
   ドを変更すると、競合条件を抑制するためにスレッドを同期化しなければ
   ならないので、推奨しません。

   単一スレッドの環境では、このコンテキストを使わないよう薦めます。下
   で述べるように明示的にコンテキストを作成してください。

   デフォルトの値は精度 28 桁、丸め規則 "ROUND_HALF_EVEN" で、トラップ
   "Overflow", "InvalidOperation", および "DivisionByZero" が有効にな
   っています。

上に挙げた三つのコンテキストに加え、 "Context" コンストラクタを使って
新たなコンテキストを生成できます。

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

   新たなコンテキストを生成します。あるフィールドが定義されていないか
   "None" であれば、 "DefaultContext" からデフォルト値をコピーします。
   *flags* フィールドが設定されていいか "None" の場合には、全てのフラ
   グがクリアされます。

   *prec* フィールドは正の整数で、コンテキストにおける算術演算の計算精
   度を設定します。

   *rounding* オプションは以下のどれか一つです:

   * "ROUND_CEILING" ("Infinity" 寄りの値に丸める),

   * "ROUND_DOWN" (ゼロ寄りの値に丸める),

   * "ROUND_FLOOR" ("-Infinity" 寄りの値に丸める),

   * "ROUND_HALF_DOWN" (近い方に、引き分けはゼロ方向に向けて丸める),

   * "ROUND_HALF_EVEN" (近い方に、引き分けは偶数整数方向に向けて丸め
     る ),

   * "ROUND_HALF_UP" (近い方に、引き分けはゼロから遠い方向に向けて丸
     め る),

   * "ROUND_UP" (ゼロから遠い値に丸める), または

   * "ROUND_05UP" (ゼロ方向に丸めた後の最後の桁が 0 または 5 ならば
     ゼ ロから遠い方向に、そうでなければゼロ方向に丸める)

   *traps* および *flags* フィールドには、セットしたいシグナルを列挙し
   ます。一般的に、新たなコンテキストを作成するときにはトラップだけを
   設定し、フラグはクリアしておきます。

   *Emin* および *Emax* フィールドには、指数の外限を整数で指定します。

   *capitals* フィールドは "0" または "1" (デフォルト) にします。 "1"
   に設定すると、指数記号を大文字 "E" で出力します。それ以外の場合には
   "Decimal('6.02e+23')" のように "e" を使います。

   バージョン 2.6 で変更: "ROUND_05UP" 丸めモードが追加されました。

   "Context" クラスでは、いくつかの汎用のメソッドの他、現在のコンテキ
   ストで算術演算を直接行うためのメソッドを数多く定義しています。加え
   て、 "Decimal" の各メソッドについて ("adjusted()" および
   "as_tuple()" メソッドを例外として) 対応する "Context" のメソッドが
   存在します。たとえば、 "Context" インスタンス  "C" と "Decimal" イ
   ンスタンス "x" に対して、 "C.exp(x)" は "x.exp(context=C)" と等価で
   す。それぞれの "Context" メソッドは、Decimal インスタンスが受け付け
   られるところならどこでも、Python の整数 ("int" または "long" のイン
   スタンス) を受け付けます。

   clear_flags()

      フラグを全て "0" にリセットします。

   copy()

      コンテキストの複製を返します。

   copy_decimal(num)

      Decimal インスタンス num のコピーを返します。

   create_decimal(num)

      *self* をコンテキストとする新たな Decimal インスタンスを *num*
      から生成します。 "Decimal" コンストラクタと違い、数値を変換する
      際にコンテキストの精度、値丸め方法、フラグ、トラップを適用します
      。

      定数値はしばしばアプリケーションの要求よりも高い精度を持っている
      ため、このメソッドが役に立ちます。また、値丸めを即座に行うため、
      例えば以下のように、入力値に値丸めを行わないために合計値にゼロの
      加算を追加するだけで結果が変わってしまうといった、現在の精度より
      も細かい値の影響が紛れ込む問題を防げるという恩恵もあります。以下
      の例は、丸められていない入力を使うということは和にゼロを加えると
      結果が変わり得るという見本です:

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

      浮動小数点数 *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):
             ...
         Inexact: None

      バージョン 2.7 で追加.

   Etiny()

      "Emin - prec + 1" に等しい値を返します。演算結果の劣化が起こる桁
      の最小値です。アンダーフローが起きた場合、指数は "Etiny" に設定
      されます。

   Etop()

      "Emax - prec + 1" に等しい値を返します。

   "Decimal" を使った処理を行う場合、通常は "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)

      *x* のコピーの符号を 0 にセットして返します。

   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)

      *e ** x* を返します。

   fma(x, y, z)

      *x* を *y* 倍したものに *z* を加えて返します。

   is_canonical(x)

      *x* が標準的(canonical)ならば "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* がゼロであれば "True" を返します。そうでなければ "False" で
      す。

   ln(x)

      *x* の自然対数(底 e の対数)を返します。

   log10(x)

      *x* の底 10 の対数を返します。

   logb(x)

      演算対象の MSD の大きさの指数部を返します。

   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)

      Python における単項マイナス演算子に対応する演算です。

   multiply(x, y)

      *x* と *y* の積を返します。

   next_minus(x)

      *x* より小さい最大の表現可能な数を返します。

   next_plus(x)

      *x* より大きい最小の表現可能な数を返します。

   next_toward(x, y)

      *x* に *y* の方向に向かって最も近い数を返します。

   normalize(x)

      *x* をもっとも単純な形にします。

   number_class(x)

      *x* のクラスを指し示すものを返します。

   plus(x)

      Python における単項のプラス演算子に対応する演算です。コンテキス
      トにおける精度や値丸めを適用するので、等値 (identity) 演算とは *
      違います*。

   power(x, y[, modulo])

      "x" の "y" 乗を計算します。"modulo" が指定されていればモジュロを
      取ります。

      二引数であれば "x**y" を計算します。 "x" が負であれば "y" は整で
      なければなりません。結果は "y" が整数であって結果が有限になり
      'precision' 桁で正確に表現できるのでなければ不正確になります。そ
      の結果は現スレッドのコンテキストの丸めモードを使って正しく丸めら
      れます。

      三引数であれば "(x**y) % modulo" を計算します。この形式の場合、
      以下の制限が引数に掛かります:

         * 全ての引数は整

         * "y" は非負でなければならない

         * "x" と "y" の少なくともどちらかはゼロでない

         * "modulo" は非零で大きくても 'precision' 桁

      "Context.power(x, y, modulo)" で得られる値は "(x**y) % modulo"
      を精度無制限で計算して得られるものと同じ値ですが、より効率的に計
      算されます。結果の指数は "x", "y", "modulo" の指数に関係なくゼロ
      です。この計算は常に正確です。

      バージョン 2.6 で変更: "x**y" 形式で "y" が非整数で構わないこと
      になりました。三引数バージョンがより厳格な要求をするようになりま
      した。

   quantize(x, y)

      *x* に値丸めを適用し、指数を *y* にした値を返します。

   radix()

      単に 10 を返します。何せ十進ですから :)

   remainder(x, y)

      整数除算の剰余を返します。

      剰余がゼロでない場合、符号は割られる数の符号と同じになります。

   remainder_near(x, y)

      "x - y * n" を返します。ここで *n* は "x / y" の正確な値に一番近
      い整数です (この結果が 0 ならばその符号は *x* の符号と同じです)
      。

   rotate(x, y)

      *x* の *y* 回巡回したコピーを返します。

   same_quantum(x, y)

      2つの演算対象が同じ指数を持っている場合に "True" を返します。

   scaleb(x, y)

      一つめの演算対象の指数部に二つめの値を加えたものを返します。

   shift(x, y)

      *x* を *y* 回シフトしたコピーを返します。

   sqrt(x)

      *x* の平方根を精度いっぱいまで求めます。

   subtract(x, y)

      *x* と *y* の間の差を返します。

   to_eng_string(x)

      文字列に変換します。指数が必要なら工学表記が使われます。

      工学表記法では指数は 3 の倍数になります。これにより、基数の小数
      部には最大で 3 桁までの数字が残されるとともに、末尾に 1 つまたは
      2 つの 0 の付加が必要とされるかもしれません。

   to_integral_exact(x)

      最近傍の整数に値を丸めます。

   to_sci_string(x)

      数値を科学表記で文字列に変換します。


9.4.4. シグナル
===============

シグナルは、計算中に生じた様々なエラー条件を表現します。各々のシグナル
は一つのコンテキストフラグと一つのトラップイネーブラに対応しています。

コンテキストフラグは、該当するエラー条件に遭遇するたびにセットされます
。演算後にフラグを調べれば、演算に関する情報 (例えば計算が厳密だったか
どうか) がわかります。フラグを調べたら、次の計算を始める前にフラグを全
てクリアするようにしてください。

あるコンテキストのトラップイネーブラがあるシグナルに対してセットされて
いる場合、該当するエラー条件が生じると Python の例外を送出します。例え
ば、 "DivisionByZero" が設定されていると、エラー条件が生じた際に
"DivisionByZero" 例外を送出します。

class decimal.Clamped

   値の表現上の制限に沿わせるために指数部が変更されたことを通知します
   。

   通常、クランプ (clamp) は、指数部がコンテキストにおける指数桁の制限
   値 "Emin" および "Emax" を越えた場合に発生します。可能な場合には、
   係数部にゼロを加えた表現に合わせて指数部を減らします。

class decimal.DecimalException

   他のシグナルの基底クラスで、 "ArithmeticError" のサブクラスです。

class decimal.DivisionByZero

   有限値をゼロで除算したときのシグナルです。

   除算やモジュロ除算、数を負の値で累乗した場合に起きることがあります
   。このシグナルをトラップしない場合、演算結果は "Infinity" または
   "-Infinity" になり、その符号は演算に使った入力に基づいて決まります
   。

class decimal.Inexact

   値の丸めによって演算結果から厳密さが失われたことを通知します。

   このシグナルは値丸め操作中にゼロでない桁を無視した際に生じます。演
   算結果は値丸め後の値です。シグナルのフラグやトラップは、演算結果の
   厳密さが失われたことを検出するために使えるだけです。

class decimal.InvalidOperation

   無効な演算が実行されたことを通知します。

   ユーザが有意な演算結果にならないような操作を要求したことを示します
   。このシグナルをトラップしない場合、 "NaN" を返します。このシグナル
   の発生原因として考えられるのは、以下のような状況です:

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

class decimal.Overflow

   数値オーバフローを示すシグナルです。

   このシグナルは、値丸めを行った後の指数部が "Emax" より大きいことを
   示します。シグナルをトラップしない場合、演算結果は値丸めのモードに
   より、表現可能な最大の数値になるように内側へ引き込んで丸めを行った
   値か、 "Infinity" になるように外側に丸めた値のいずれかになります。
   いずれの場合も、 "Inexact" および "Rounded" が同時にシグナルされま
   す。

class decimal.Rounded

   情報が全く失われていない場合も含み、値丸めが起きたときのシグナルで
   す。

   このシグナルは、値丸めによって桁がなくなると常に発生します。なくな
   った桁がゼロ (例えば "5.00" を丸めて "5.0" になった場合) であっても
   です。このシグナルをトラップしなければ、演算結果をそのまま返します
   。このシグナルは有効桁数の減少を検出する際に使います。

class decimal.Subnormal

   値丸めを行う前に指数部が "Emin" より小さかったことを示すシグナルで
   す。

   演算結果が微小である場合 (指数が小さすぎる場合) に発生します。この
   シグナルをトラップしなければ、演算結果をそのまま返します。

class decimal.Underflow

   演算結果が値丸めによってゼロになった場合に生じる数値アンダフローで
   す。

   演算結果が微小なため、値丸めによってゼロになった場合に発生します。
   "Inexact" および "Subnormal" シグナルも同時に発生します。

これらのシグナルの階層構造をまとめると、以下の表のようになります:

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


9.4.5. 浮動小数点数に関する注意
===============================


9.4.5.1. 精度を上げて丸め誤差を抑制する
---------------------------------------

10進浮動小数点数を使うと、10進数表現による誤差を抑制できます ("0.1" を
正確に表現できるようになります); しかし、ゼロでない桁が一定の精度を越
えている場合には、演算によっては依然として値丸めによる誤差を引き起こし
ます。

値丸めによる誤差の影響は、桁落ちを生じるような、ほとんど相殺される量で
の加算や減算によって増幅されます。Knuth は、十分でない計算精度の下で値
丸めを伴う浮動小数点演算を行った結果、加算の結合則や分配則における恒等
性が崩れてしまう例を二つ示しています:

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


9.4.5.2. 特殊値
---------------

"decimal" モジュールの数体系では、 "NaN", "sNaN", "-Infinity",
"Infinity", および二つのゼロ、 "+0" と "-0" といった特殊な値を提供して
います。

無限大 (Infinity) は "Decimal('Infinity')" で直接構築できます。また、
"DivisionByZero" をトラップせずにゼロで除算を行った場合にも出てきます
。同様に、 "Overflow" シグナルをトラップしなければ、表現可能な最大の数
値の制限を越えた値を丸めたときに出てきます。

無限大には符号があり (アフィン: affine であり)、算術演算に使用でき、非
常に巨大で不確定の(indeterminate)値として扱われます。例えば、無限大に
何らかの定数を加算すると、演算結果は別の無限大になります。

演算によっては結果が不確定になるものがあり、 "NaN" を返します。ただし
、 "InvalidOperation" シグナルをトラップするようになっていれば例外を送
出します。例えば、 "0/0" は "NaN" を返します。 "NaN" は「非数値 (not a
number)」を表します。このような "NaN" は暗黙のうちに生成され、一度生成
されるとそれを他の計算にも流れてゆき、関係する個々の演算全てが個別の
"NaN" を返すようになります。この挙動は、たまに入力値が欠けるような状況
で一連の計算を行う際に便利です --- 特定の計算に対しては無効な結果を示
すフラグを立てつつ計算を進められるからです。

一方、 "NaN" の変種である "sNaN" は関係する全ての演算で演算後にシグナ
ルを送出します。 "sNaN" は、無効な演算結果に対して特別な処理を行うため
に計算を停止する必要がある場合に便利です。

Python の比較演算は "NaN" が関わってくると少し驚くようなことがあります
。等価性のテストの一方の対象が無言または発信 "NaN" である場合いつでも
"False" を返し(たとえ "Decimal('NaN')==Decimal('NaN')" でも)、一方で不
等価をテストするといつでも "True" を返します。二つの Decimal を "<",
"<=", ">" または ">=" を使って比較する試みは一方が "NaN" である場合に
は "InvalidOperation" シグナルを送出し、このシグナルをトラップしなけれ
ば結果は "False" に終わります。汎用10進演算仕様は直接の比較の振る舞い
について定めていないことに注意しておきましょう。ここでの "NaN" が関係
する比較ルールは IEEE 854 標準から持ってきました (section 5.7 の Table
3 を見て下さい)。厳格に標準遵守を貫くなら、 "compare()" および
"compare-signal()" メソッドを代わりに使いましょう。

アンダフローの起きた計算は、符号付きのゼロ (signed zero) を返すことが
あります。符号は、より高い精度で計算を行った結果の符号と同じになります
。符号付きゼロの大きさはやはりゼロなので、正のゼロと負のゼロは等しいと
みなされ、符号は単なる参考にすぎません。

二つの符号付きゼロが区別されているのに等価であることに加えて、異なる精
度におけるゼロの表現はまちまちなのに、値は等価とみなされるということが
あります。これに慣れるには多少時間がかかります。正規化浮動小数点表現に
目が慣れてしまうと、以下の計算でゼロに等しい値が返っているとは即座に分
かりません:

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


9.4.6. スレッドを使った処理
===========================

関数 "getcontext()" は、スレッド毎に別々の "Context" オブジェクトにア
クセスします。別のスレッドコンテキストを持つということは、複数のスレッ
ドが互いに影響を及ぼさずに ("getcontext().prec=10" のような) 変更を適
用できるということです。

同様に、"setcontext()" 関数は自動的に引数のコンテキストを現在のスレッ
ドのコンテキストに設定します。

"getcontext()" を呼び出す前に "setcontext()" が呼び出されていなければ
、現在のスレッドで使うための新たなコンテキストを生成するために
"getcontext()" が自動的に呼び出されます。

新たなコンテキストは、*DefaultContext* と呼ばれる雛形からコピーされま
す。アプリケーションを通じて全てのスレッドに同じ値を使うようにデフォル
トを設定したければ、*DefaultContext* オブジェクトを直接変更します。
"getcontext()" を呼び出すスレッド間で競合条件が生じないようにするため
、*DefaultContext* への変更はいかなるスレッドを開始するよりも *前に*
行わなければなりません。以下に例を示します:

   # 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()
    . . .


9.4.7. レシピ
=============

"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 = map(str, digits)
       build, next = result.append, digits.pop
       if sign:
           build(trailneg)
       for i in range(places):
           build(next() if digits else '0')
       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.

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

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


9.4.8. Decimal FAQ
==================

Q. "decimal.Decimal('1234.5')" などと打ち込むのは煩わしいのですが、対
話式インタプリタを使う際にタイプ量を少なくする方法はありませんか?

A. コンストラクタを1文字に縮める人もいるようです:

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

Q. 小数点以下2桁の固定小数点数のアプリケーションの中で、いくつかの入力
が余計な桁を保持しているのでこれを丸めなければなりません。その他のもの
に余計な桁はなくそのまま使えます。どのメソッドを使うのがいいでしょうか
?

A. "quantize()" メソッドで固定した桁に丸められます。 "Inexact" トラッ
プを設定しておけば、確認にも有用です:

>>> 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. 正当な2桁の入力が得られたとして、その正当性をアプリケーション実行中
も変わらず保ち続けるにはどうすればいいでしょうか?

A. 加減算あるいは整数との乗算のような演算は自動的に固定小数点を守りま
す。その他の除算や整数以外の乗算などは小数点以下の桁を変えてしまいます
ので実行後は "quantize()" ステップが必要です:

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

固定小数点のアプリケーションを開発する際は、 "quantize()" の段階を扱う
関数を定義しておくと便利です:

>>> 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. 一つの値に対して多くの表現方法があります。 "200" と "200.000" と
"2E2" と "02E+4" は全て同じ値で違った精度の数です。これらをただ一つの
正規化された値に変換することはできますか?

A. "normalize()" メソッドは全ての等しい値をただ一つの表現に直します:

>>> 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. ある種の10進数値はいつも指数表記で表示されます。指数表記以外の表示
にする方法はありますか?

A. 値によっては、指数表記だけが有効桁数を表せる表記法なのです。たとえ
ば、 "5.0E+3" を "5000" と表してしまうと、値は変わりませんが元々の2桁
という有効数字が反映されません。

もしアプリケーションが有効数字の追跡を等閑視するならば、指数部や末尾の
ゼロを取り除き、有効数字を忘れ、しかし値を変えずにおくことは容易です:

   def remove_exponent(d):
       '''Remove exponent and trailing zeros.

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

       '''
       return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()

Q. 普通の float を "Decimal" に変換できますか?

A. はい。どんな 2 進浮動小数点数も Decimal として正確に表現できます。
ただし、正確な変換は直感的に考えたよりも多い桁になることがあります:

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

Q. 複雑な計算の中で、精度不足や丸めの異常で間違った結果になっていない
ことをどうやって保証すれば良いでしょうか。

A. decimal モジュールでは検算は容易です。一番良い方法は、大きめの精度
や様々な丸めモードで再計算してみることです。大きく異なった結果が出てき
たら、精度不足や丸めの問題や悪条件の入力、または数値計算的に不安定なア
ルゴリズムを示唆しています。

Q. コンテキストの精度は計算結果には適用されていますが入力には適用され
ていないようです。様々に異なる精度の入力値を混ぜて計算する時に注意すべ
きことはありますか?

A. はい。原則として入力値は正確であると見做しておりそれらの値を使った
計算も同様です。結果だけが丸められます。入力の強みは "what you type is
what you get" (打ち込んだ値が得られる値)という点にあります。入力が丸め
られないということを忘れていると結果が奇妙に見えるというのは弱点です:

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