web-dev-qa-db-ja.com

Pythonで数値を丸めますが、末尾のゼロは保持します

私は、Excelスプレッドシートからデータを取得し、数値を丸め、小数点を削除するスクリプトに取り組んでいます。たとえば、2606.89579999999は26069になります。末尾のゼロなので、2606.89579999999は260690になります。

現在、iはExcelのセルからデータを取得し、小数点以下2桁に丸めます(i = round(i, 2))。これにより、上記の例では1つの小数点が得られます。

Decimalでこれを機能させる方法を考えてみましたが、機能していないようです。

丸められた値が「0」で終わらない場合、丸められる他のすべての数値はround(i, 2)で正常に機能しますが、数値が偶然* .x0で終わる場合、その0は破棄されますそしてデータをめちゃくちゃにします。

20
Seth Koberg

末尾のゼロについて話しているように、これは文字列としての表現に関する質問です。

>>> "%.2f" % round(2606.89579999999, 2)
'2606.90'

または、format関数でモダンなスタイルを使用します。

>>> '{:.2f}'.format(round(2606.89579999999, 2))
'2606.90'

replaceまたはtranslateでポイントを削除します(_は、python console)の前のコマンドの結果を参照します):

>>> _.translate(None, '.')
'260690'

.2f形式では同じ丸めが適用されるため、ここでは丸めが必要ないことに注意してください。

>>> "%.2f" % 2606.89579999999
'2606.90'

しかし、Excelについて述べたように、おそらくfloat.roundは浮動小数点表現による奇妙な結果につながる可能性があるため、独自の丸め関数を使用するか、 decimal を使用することを選択するでしょう。

>>> round(2.675, 2)
2.67
>>> round(2606.89579999999, 2)
2606.89

10進数の使用 quantize

>>> from decimal import *
>>> x = Decimal('2606.8950000000001')
# Decimal('2606.8950000000001')
>>> '{}'.format(x.quantize(Decimal('.01'), rounding=ROUND_HALF_EVEN))
'2606.90'

元のタスクでは、次のようになります。

>>> x = Decimal('2606.8950000000001')
>>> int((x*100).quantize(1, rounding=ROUND_HALF_EVEN))
260690

そして、奇妙な丸めの理由はDecimalで前面に来ます:

>>> x = Decimal(2606.8950000000001)
# Decimal('2606.89499999999998181010596454143524169921875') # internal float repr
33
alko
>>> '{:.2f}'.format(2606.89579999999).replace('.', '')
'260690'
3
Maciej Gol