web-dev-qa-db-ja.com

Pythonで小数点以下2桁に切り上げ

Pythonで数値を小数点第2位に切り上げるにはどうすればよいですか?例えば:

0.022499999999999999

0.03に切り上げます

0.1111111111111000

0.12に切り上げます

小数点第3位に値がある場合、常に小数点以下2つの値を残して切り上げてほしい。

43
user1202589

Pythonにはround()関数が含まれており、これは 指定可能 必要な桁数です。ドキュメントから:

round(x[, n])

小数点以下n桁に丸められた浮動小数点値xを返します。 nを省略すると、デフォルトでゼロになります。結果は浮動小数点数です。値は、10のマイナスnに最も近い倍数に丸められます。 2つの倍数が等しく近い場合、丸めは0から離れて行われます(たとえば、round(0.5)は1.0で、round(-0.5)は-1.0です)。

したがって、通常の丸めを行うには、round(x, 2)を使用します。数値が常に丸められるupを保証するには、ceil(x)関数を使用する必要があります。同様に、downを丸めるには、floor(x)を使用します。

48
simchona
from math import ceil

num = 0.1111111111000
num = ceil(num * 100) / 100.0

見る:
math.ceilドキュメント
round documentation -おそらく今後の参考のためにこれをチェックアウトすることをお勧めします

26
Edwin

エドウィンの答えから外挿:

from math import ceil, floor
def float_round(num, places = 0, direction = floor):
    return direction(num * (10**places)) / float(10**places)

使用するには:

>>> float_round(0.21111, 3, ceil)  #round up
>>> 0.212
>>> float_round(0.21111, 3)        #round down
>>> 0.211
>>> float_round(0.21111, 3, round) #round naturally
>>> 0.211
13
Patrick Perini
x = math.ceil(x * 100.0) / 100.0
11
Mark Ransom

これは、正の数と負の数を検討するときに必要な動作に依存しますが、常により大きな値に丸める何かが必要な場合(例:2.0449-> 2.05、-2.0449-> -2.04)、次のことができます:

round(x + 0.005, 2)

または少し手の込んだ:

def round_up(x, place):
    return round(x + 5 * 10**(-1 * (place + 1)), place)

これも次のように機能するようです:

round(144, -1)
# 140
round_up(144, -1)
# 150
round_up(1e308, -307)
# 1.1e308
10
ajp619

ceil(num * 100) / 100トリックは、1e308などの一部の縮退入力でクラッシュすることに注意してください。これはそれほど頻繁には起こらないかもしれませんが、数日かかるだけだと言えます。これを回避するために、ceil()floor()は、 round() のように小数点以下の引数を取ります。 。一方、誰かがこのような入力でクラッシュしないクリーンな代替手段を知っていますか? decimal パッケージにはいくつかの希望がありましたが、それも死にそうです:

>>> from math import ceil
>>> from decimal import Decimal, ROUND_DOWN, ROUND_UP
>>> num = 0.1111111111000
>>> ceil(num * 100) / 100
0.12
>>> float(Decimal(num).quantize(Decimal('.01'), rounding=ROUND_UP))
0.12
>>> num = 1e308
>>> ceil(num * 100) / 100
Traceback (most recent call last):
  File "<string>", line 301, in runcode
  File "<interactive input>", line 1, in <module>
OverflowError: cannot convert float infinity to integer
>>> float(Decimal(num).quantize(Decimal('.01'), rounding=ROUND_UP))
Traceback (most recent call last):
  File "<string>", line 301, in runcode
  File "<interactive input>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]

もちろん、クラッシュはそのような入力に対する唯一の正気な動作であると言うかもしれませんが、私はそれが丸めではなく、問題を引き起こしている乗算であると主張します(そのため、たとえば1e306はクラッシュしません) n桁目の切り上げfnは乗算ハックを回避します。

4
Jacob Eliosoff
def round_up(number, ndigits=None):
    # start by just rounding the number, as sometimes this rounds it up
    result = round(number, ndigits if ndigits else 0)
    if result < number:
        # whoops, the number was rounded down instead, so correct for that
        if ndigits:
            # use the type of number provided, e.g. float, decimal, fraction
            Numerical = type(number)
            # add the digit 1 in the correct decimal place
            result += Numerical(10) ** -ndigits
            # may need to be tweaked slightly if the addition was inexact
            result = round(result, ndigits)
        else:
            result += 1 # same as 10 ** -0 for precision of zero digits
    return result

assert round_up(0.022499999999999999, 2) == 0.03
assert round_up(0.1111111111111000, 2) == 0.12

assert round_up(1.11, 2) == 1.11
assert round_up(1e308, 2) == 1e308
2

python round関数は、予期しない方法で丸められている可能性があります。

Decimal.quantizeを使用して、丸め方法をより具体的にすることができます。

例えば。

from decimal import Decimal, ROUND_HALF_UP
res = Decimal('0.25').quantize(Decimal('0.0'), rounding=ROUND_HALF_UP)
print(res) 
# prints 0.3

その他の参照:

https://Gist.github.com/jackiekazil/6201722

0
James Lin

記載されているラウンド関数は、次のような整数の定義には機能しません。

a = 8
round(a、3)
8.0
a = 8.00
round(a、3)
8.0
a = 8.000000000000000000000000
round(a、3)
8.0

しかし、のために働く:

r = 400/3.0
r
133.33333333333334
round(r、3)
133.333

さらに、2.675のような小数は2.68ではなく2.67に丸められます。
上記の他の方法を使用してください。

0
Shikhar