web-dev-qa-db-ja.com

浮動小数点数を特定の小数位に切り上げるにはどうすればよいですか?

8.8333333333333339があり、それを8.84に変換したいとします。 Pythonでこれを達成するにはどうすればよいですか?

round(8.8333333333333339, 2)8.83ではなく8.84を提供します。私はPythonまたはプログラミング全般に不慣れです。

文字列として出力したくないので、結果はさらに使用されます。問題の詳細については、ティムウィルソンのPythonプログラミングのヒント:ローンと支払い計算機を確認してください。 。

76
hsinxh

8.833333333339(または8.833333333333334106.00/12の結果)は、小数点以下2桁に適切に丸められた8.83です。数学的には、欲しいものは 天井関数 のように聞こえます。 Pythonのmathモジュールの名前は ceil

import math

v = 8.8333333333333339
print(math.ceil(v*100)/100)  # -> 8.84

それぞれ、floor関数とceiling関数は、通常、実数を小数点以下の桁数がゼロの最大の前または最小の整数にマッピングします。したがって、小数点以下2桁で使用するには、数値に最初に10を掛けます。2 (または100)小数点をシフトし、その後、補正するために小数点で除算されます。

何らかの理由でmathモジュールを使用したくない場合は、先ほど書いたこの(最小限のテスト済み)実装を使用できます。

def ceiling(x):
    n = int(x)
    return n if n-1 < x <= n else n+1

これがリンクに適用される方法 ローンと支払い計算機の問題

screenshot of loan calculator output

サンプル出力から、彼らは切り上げられた多くの人が呼ぶものである毎月の支払い天井関数の効果。これは、毎月よりも少し多いことを意味します 112 合計金額のうち支払われています。これにより、最終的な支払いは通常よりも少し少なくなり、未払いの残高は8.76だけになりました。

8.83の毎月の支払いと8.87のわずかに高い最終支払いを生成する通常の丸めを使用することも同様に有効でした。しかし、現実の世界では、人々は一般的に支払いを増やすことを好まないため、各支払いを切り上げることは一般的な習慣です。また、より迅速に貸し手にお金を返します。

95
martineau

これは正常です (そしてPythonとは何の関係もありません)1/3が10進数(0.333333 ... ad infinitum)で正確に表現できないのと同様に、8.83はバイナリ浮動小数点として正確に表現できないためです。

絶対精度を確保したい場合は、 decimal モジュールが必要です:

>>> import decimal
>>> a = decimal.Decimal("8.833333333339")
>>> print(round(a,2))
8.83
63
Tim Pietzcker

Decimalモジュールを使用したいが、丸めモードを指定する必要もあります。以下に例を示します。

>>> import decimal
>>> decimal.Decimal('8.333333').quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_UP)
Decimal('8.34')
>>> decimal.Decimal('8.333333').quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_DOWN)
Decimal('8.33')
>>> 
22
casevh

もっと簡単な方法は、単にround()関数を使用することです。以下に例を示します。

total_price = float()
price_1 = 2.99
price_2 = 0.99
total_price = price_1 + price_2

今すぐtotal_priceを印刷すると、

3.9800000000000004

ただし、次のようにround()関数で囲む場合

print(round(total_price,2))

出力は等しい

3.98

Round()関数は、2つのパラメーターを受け入れることで機能します。最初は、丸めたい数値です。 2番目は、丸める小数点以下の桁数です。

11
user2252471

8.8333333333339を小数点以下2桁に丸めると、正解は8.84ではなく8.83になります。 8.83000000001を取得した理由は、8.83がバイナリで正しく表現できない数値であり、最も近い数値が得られるためです。すべてゼロなしで印刷したい場合は、VGEの説明に従ってください:

print "%.2f" % 8.833333333339   #(Replace number with the variable?)

丸めたい場合は、8.84が間違った答えです。丸められた8.833333333333は8.84ではなく8.83です。常に切り上げたい場合は、math.ceilを使用できます。浮動小数点数自体を丸めることは意味をなさないため、文字列の書式設定と組み合わせて両方を行います。

"%.2f" % (math.ceil(x * 100) / 100)
5
Rosh Oxymoron

これを行う最も簡単な方法は、組み込みの以下の関数を使用することです。

format()

例えば:

format(1.242563,".2f")

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

1.24

同様に:

format(9.165654,".1f")

与えるだろう:

9.2
3

記録のためだけに。次のようにできます。

def roundno(no):
    return int(no//1 + ((no%1)/0.5)//1)

そこには、インクルード/インポートの必要はありません

3
twohot

decimalモジュールを使用します。 http://docs.python.org/library/decimal.html

ََََََ

1
orip

切り上げ/切り捨ての問題に対する私の解決策は次のとおりです

< .5  round down

> = .5  round up

import math

def _should_round_down(val: float):
    if val < 0:
        return ((val * -1) % 1) < 0.5
    return (val % 1) < 0.5

def _round(val: float, ndigits=0):
    if ndigits > 0:
        val *= 10 ** (ndigits - 1)
    is_positive = val > 0
    tmp_val = val
    if not is_positive:
        tmp_val *= -1
    rounded_value = math.floor(tmp_val) if _should_round_down(val) else math.ceil(tmp_val)
    if not is_positive:
        rounded_value *= -1
    if ndigits > 0:
        rounded_value /= 10 ** (ndigits - 1)
    return rounded_value

# test
# nr = 12.2548
# for digit in range(0, 4):
#     print("{} decimals : {} -> {}".format(digit, nr, _round(nr, digit)))

# output
# 0 decimals : 12.2548 -> 12
# 1 decimals : 12.2548 -> 12.0
# 2 decimals : 12.2548 -> 12.3
# 3 decimals : 12.2548 -> 12.25
1
opra

これを行うための簡単な関数を次に示します。

def precision(num,x):
    return "{0:.xf}".format(round(num))

ここで、numは10進数です。 xは、浮動小数点数を四捨五入するまでの小数です。

他の実装に勝る利点は、小数点の右端のゼロを埋めて、小数点以下x桁までのdeciaml番号を作成できることです。

例1:

precision(10.2, 9)

戻ります

10.200000000(小数点以下9桁まで)

例2:

precision(10.2231, 2)

戻ります

10.22(最大2桁の小数点)

0
Akash Kandpal

私はこのコードを持っています:

tax = (tax / 100) * price

そして、このコード:

tax = round((tax / 100) * price, 2)

ラウンドは私のために働いた

0
Nic56