web-dev-qa-db-ja.com

形式Python指定された精度の10進オブジェクト

私は数え切れないほどの時間を調査、読み取り、テストに費やし、PythonのDecimalオブジェクトに最も基本的な概念であるDecimalの出力を文字列にフォーマットすることがないことに最終的に混乱して落胆しました。

次の値を持つ文字列またはDecimalオブジェクトがあると仮定します。

   0.0008
  11.1111
 222.2222
3333.3333
1234.5678

目標は、小数点以下の桁数を小数点以下2桁に設定することです。たとえば、11.111111.11としてフォーマットされ、1234.56781234.57としてフォーマットされます。

私は次のようなコードを想定しています。

import decimal
decimals = [
  decimal.Decimal('0.0008'),
  decimal.Decimal('11.1111'),
  decimal.Decimal('222.2222'),
  decimal.Decimal('3333.3333'),
  decimal.Decimal('1234.5678'),
]
for dec in decimals:
  print dec.as_string(precision=2, rounding=ROUND_HALF_UP)

結果の出力は次のようになります。

0.00
11.11
222.22
3333.33
1234.57

明らかに、Decimalのコンテキストの精度を利用することはできません。これは、10進数の精度だけでなく、合計桁数が考慮されるためです。

また、Decimalをfloatに変換してその値を出力することにも興味がありません。 Decimalの背後にあるすべての理由は、フロートでの計算の保存と実行を回避するためです。

他にどのような解決策がありますか?スタックオーバーフローについては他にも多くの同様の質問があることを理解していますが、私が尋ねている根本的な問題を解決するためにそれらのどれも見つけられませんでした。

どうもありがとう!

16
Joshua Burns

文字列フォーマット または format() function を使用するだけです。

_>>> for dec in decimals:
...    print format(dec, '7.2f')
... 
   0.00
  11.11
 222.22
3333.33
1234.57
_

_decimal.Decimal_はfloatと同じ フォーマット仕様 をサポートしているため、必要に応じて指数、固定小数点、一般、数値、またはパーセンテージのフォーマットを使用できます。

これは、小数をフォーマットする公式のPythonicメソッドです。 Decimalクラスは.__format__()メソッドを実装して、このようなフォーマットを効率的に処理します。

27
Martijn Pieters
def d(_in, decimal_places = 3):
    ''' Convert number to Decimal and do rounding, for doing calculations
        Examples:
          46.18271  to   46.183   rounded up
          46.18749  to   46.187   rounded down
          117.34999999999999 to 117.350
         _rescale is a private function, bad practice yet works for now.
    '''
    return Decimal(_in)._rescale(-decimal_places, 'ROUND_HALF_EVEN')

編集:繰り返しますが、_rescale()は通常のBipedで使用するためのものではなく、Python 2.7で動作し、3.4では使用できません。

2
gseattle