1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Python】小数点以下の値の丸め(切り捨て)

Posted at

Pythonで小数点以下の数値を切り捨てたいときを考えます。例えば、10.987654321と入力した場合に、小数点2位まで取り出して、10.98と返してくれるような関数を考えます。

環境

  • Windows 10
  • python=3.7.3

方法① (精度に問題あり)

値を100倍して、Intにして、100で割る

def round_off_to_two_decimal_places_1(input_val: float) -> float:
    output = int(input_val * 100) / 100
    return output


def round_off_test(round_off_method):
    input_val = 10.987654321
    print(input_val, "->", round_off_method(input_val))
    input_val = 10.12
    print(input_val, "->", round_off_method(input_val))
    input_val = 10.99
    print(input_val, "->", round_off_method(input_val))
    input_val = 10.74297492
    print(input_val, "->", round_off_method(input_val))
    input_val = 10.155
    print(input_val, "->", round_off_method(input_val))
    input_val = 10.585018
    print(input_val, "->", round_off_method(input_val))
    input_val = 10.000000
    print(input_val, "->", round_off_method(input_val))
    input_val = 10.
    print(input_val, "->", round_off_method(input_val))
    print("")


round_off_test(round_off_to_two_decimal_places_1)

実行結果
10.987654321 -> 10.98
10.12 -> 10.11
10.99 -> 10.99
10.74297492 -> 10.74
10.155 -> 10.15
10.585018 -> 10.58
10.0 -> 10.0
10.0 -> 10.0

良さそうに見えますが、10.12を入力した場合に10.11と返されてしまっています。

方法②

文字列として操作する。

def round_off_to_two_decimal_places_2(input_val: float) -> float:
    str_input_val = str(input_val)
    split_str = str_input_val.split('.')
    if len(split_str[1]) > 2:
        split_str[1] = split_str[1][:2]  # 小数点以下2桁取り出す
    str_output = '.'.join(split_str)
    return float(str_output)


round_off_test(round_off_to_two_decimal_places_2)

実行結果
10.987654321 -> 10.98
10.12 -> 10.12
10.99 -> 10.99
10.74297492 -> 10.74
10.155 -> 10.15
10.585018 -> 10.58
10.0 -> 10.0
10.0 -> 10.0

力技ですが、一応意図した値は返してくれるようです。

方法③

Decimalのquantizeメソッドを使う。

from decimal import Decimal, ROUND_DOWN


def round_off_to_two_decimal_places_3(input_val: float) -> float:
    TWOPLACES = Decimal(10) ** -2
    output = Decimal(str(input_val)).quantize(TWOPLACES, rounding=ROUND_DOWN)
    return float(output)


round_off_test(round_off_to_two_decimal_places_3)
実行結果
10.987654321 -> 10.98
10.12 -> 10.12
10.99 -> 10.99
10.74297492 -> 10.74
10.155 -> 10.15
10.585018 -> 10.58
10.0 -> 10.0
10.0 -> 10.0

意図した値が返ってきてます。

補足

ContextのtrapsにInexactを設定すると、丸めが発生したことを通知することもできます。

from decimal import Decimal, ROUND_DOWN, Context, Inexact


def round_off_to_two_decimal_places_4(input_val: float) -> float:
    TWOPLACES = Decimal(10) ** -2
    try:
        output = Decimal(str(input_val)).quantize(
            TWOPLACES, rounding=ROUND_DOWN, context=Context(traps=[Inexact]))
    except Inexact:
        print("値の丸めが発生")
        output = Decimal(str(input_val)).quantize(TWOPLACES,
                                                  rounding=ROUND_DOWN)
    return float(output)


round_off_test(round_off_to_two_decimal_places_4)

実行結果
値の丸めが発生
10.987654321 -> 10.98
10.12 -> 10.12
10.99 -> 10.99
値の丸めが発生
10.74297492 -> 10.74
値の丸めが発生
10.155 -> 10.15
値の丸めが発生
10.585018 -> 10.58
10.0 -> 10.0
10.0 -> 10.0

結果

Pythonで浮動小数点を扱う場合は、Decimalを使うのがよさそうです。

参考URL

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?