Pythonの勉強をしていて、このような悩みを抱えていませんか?
四捨五入のやり方が分からない…
この記事では、Pythonでの四捨五入する方法について現役エンジニアが分かりやすく解説していきます。
他にも【Python入門】if文の使い方や【Python入門】for文の使い方で「if」や「for」について分かりやすく解説しているので、お時間がある方はご確認ください。
また、Pythonをもっと詳しく勉強したいという方は、【超厳選】20代におすすめのプログラミングスクール3選!を参考にしてください。
他にも無料でプログラミングスクールを受講したいという方は、【完全無料】0円で学べるプログラミングスクールを紹介【大学生向け】を参考にしてください。
四捨五入する方法は2通り
Pythonで四捨五入する方法は2通りあります。
- round()(不安定)
- decimalモジュールのROUND_HALF_UPモード(安定)
ここで注目していただきたいのは、不安定と安定ということです。
ここでいう安定とは、必ず正確な四捨五入した結果が得られることです。
つまり、不安定な四捨五入であるround()はある条件下の場合は、正確な四捨五入をすることが出来ません。
ここからは、安定と不安定について詳しく解説していきます。
不安定な四捨五入の場合はround()
まずは、Round()関数の書き方から見ていきましょう。
round(四捨五入する値, 四捨五入後の桁数)
第二引数の「四捨五入後の桁数」は、値が無くてもround()は動作します。
そのため、第一引数のみの場合と第二引数がある場合の2通りの使い方を解説していきます。
①第一引数のみ
まずは、以下の例コードをコピペして実行してください。
num1 = round(1.3)
num2 = round(1.333)
num3 = round(2.987)
num4 = round(2.5)
print(num1)
print(num2)
print(num3)
print(num4)
実行すると、次のような出力が得られます。
1
1
3
2
round()では、第一引数のみに値を設定すると、小数第一位で四捨五入されることが分かります。
ここで、注目して欲しいのは、変数num4の出力結果です。
本当は、「3」と出力されるはずが「2」となっています。これが不安定な四捨五入と書いている理由です。
なぜ、このような出力結果になるのかは後ほど解説していきますので、今は「そういう時もあるのか」くらいに思っていただければ大丈夫です。
②第二引数あり
次に、第二引数がある場合の解説です。
第二引数は、正の値が設定されると小数点以降の桁数、負の値が設定されると整数の桁数を指定して四捨五入することが出来ます。
具体的に解説するためにまずは、以下の例コードをコピペして実行してください。
num1 = round(1.23456789, 1)
num2 = round(1.23456789, 4)
num3 = round(12345678.9, -1)
num4 = round(12345678.9, -4)
print(num1)
print(num2)
print(num3)
print(num4)
実行すると、次のような出力が得られます。
1.2
1.2346
12345680.0
12350000.0
「num1 = round(1.23456789, 1)」は、第二引数に正の値が設定されているので、小数点以降の桁数となり、「1」が設定されているので、小数第一位まで表示、つまり、小数第二位を四捨五入します。
「num2 = round(1.23456789, 4)」は、第二引数に正の値が設定されているので、小数点以降の桁数となり、「4」が設定されているので、小数第四位まで表示、つまり、小数第五位を四捨五入します。
「num3 = round(12345678.9, -1)」は、第二引数に負の値が設定されているので、整数の桁数となり、「-1」が設定されているので、一の位を四捨五入します。
「num4 = round(12345678.9, -4)」は、第二引数に負の値が設定されているので、整数の桁数となり、「-4」が設定されているので、千の位を四捨五入します。
不安定な四捨五入の理由
不安定な四捨五入とは、正確な四捨五入の出力結果が得られない場合があることと説明しました。
実際に、以下のコードでは求めている値とは異なる値が得られます。
num = round(2.5)
print(num)
実行すると、次のような出力が得られます。
2
本当は、「3」と表示されるべきですが、「2」と出力されてしまっています。
これは、round()の仕様による影響です。
Pythonの公式ページでround()は、以下のように注釈されています。
round() をサポートする組み込み型では、値は 10 のマイナス ndigits 乗の倍数の中で最も近いものに丸められます; 二つの倍数が同じだけ近いなら、偶数を選ぶ方に (そのため、例えば round(0.5) と round(-0.5) は両方とも 0 に、 round(1.5) は 2 に) 丸められます。 ~(中略)~ 浮動小数点数に対する round() の振る舞いは意外なものかもしれません: 例えば、 round(2.675, 2) は予想通りの 2.68 ではなく 2.67 を与えます。これはバグではありません: これはほとんどの小数が浮動小数点数で正確に表せないことの結果です。
参照:https://docs.python.org/ja/3/library/functions.html#round
これを簡単に説明していきます。
四捨五入する値が「0~4」の場合は切り捨て、「6~9」の場合は切り上げ、これについては特に問題ありません。
注意すべきは、四捨五入する値が「5」の時です。
四捨五入する値が「5」の場合は、切り捨てた結果が偶数になる場合は切り捨て、切り上げた結果が偶数になる場合は切り上げをします。
表にまとめると以下の通りです。
四捨五入する値 | 結果 |
---|---|
0 ~ 4 | 切り捨て |
5 | 切り捨てた結果が偶数になる場合は切り捨て 切り上げた結果が偶数になる場合は切り上げ |
6 ~ 9 | 切り上げ |
さらに、実際に以下のコードを実行して、より理解を深めていきましょう。
num1 = round(1.5)
num2 = round(2.5)
num3 = round(3.5)
num4 = round(4.5)
print(num1)
print(num2)
print(num3)
print(num4)
実行結果は、次の通りです。
2
2
4
4
「num1 = round(1.5)」の場合は、小数第一位を切り捨てると「1」で奇数、切り上げると「2」で偶数となるため、出力は偶数の「2」となります。
「num2 = round(2.5)」の場合は、小数第一位を切り捨てると「2」で偶数、切り上げると「3」で奇数となるため、出力は偶数の「2」となります。
「num3 = round(3.5)」の場合は、小数第一位を切り捨てると「3」で奇数、切り上げると「4」で偶数となるため、出力は偶数の「4」となります。
「num4 = round(4.5)」の場合は、小数第一位を切り捨てると「4」で奇数、切り上げると「5」で偶数となるため、出力は偶数の「4」となります。
安定な四捨五入の場合はdecimalモジュールのROUND_HALF_UPモード
decimalモジュールのROUND_HALF_UPモードの書き方は、以下の通りです。
Decimal(四捨五入する値).quantize(Decimal(丸める桁数), rounding=ROUND_HALF_UP)
まずは、以下のコードをコピペして実行してください。
# decimalモジュールからDecimal, ROUND_HALF_UPを使用
from decimal import Decimal, ROUND_HALF_UP
num1 = 1.5
num2 = 2.5
num3 = 3.5
num4 = 4.5
# 小数第一位を四捨五入
result1 = Decimal(num1).quantize(Decimal('1'), rounding=ROUND_HALF_UP)
result2 = Decimal(num2).quantize(Decimal('1'), rounding=ROUND_HALF_UP)
result3 = Decimal(num3).quantize(Decimal('1'), rounding=ROUND_HALF_UP)
result4 = Decimal(num4).quantize(Decimal('1'), rounding=ROUND_HALF_UP)
print(result1)
print(result2)
print(result3)
print(result4)
実行すると、次のような出力が得られます。
2
3
4
5
round()では、正しい値が得られなかった数値も正しい値が出力されました。
もう一度おさらいするために、再度decimalモジュールのROUND_HALF_UPモードの使い方を確認しましょう。
Decimal(四捨五入する値).quantize(Decimal(丸める桁数), rounding=ROUND_HALF_UP)
「丸める桁数」は、小数第一位を四捨五入する場合は「1」、小数第二位を四捨五入する場合は「0.1」、小数第三位を四捨五入する場合は「0.01」となっています。
【まとめ】四捨五入する際には注意が必要
Pythonで四捨五入する方法は分かりましたか?
四捨五入する方法は、以下の2通りです。
round(四捨五入する値, 四捨五入後の桁数)
Decimal(四捨五入する値).quantize(Decimal(丸める桁数), rounding=ROUND_HALF_UP)
ただし、round()は不安定な四捨五入となっているので注意しましょう。
この記事では、Pythonの四捨五入の使い方について紹介しました。
最後になりますが、私の体験談やみなさんの疑問に対して、できる限り分かりやすく記載したつもりです。ですが、もしここに関してもっと詳しく教えて欲しいときなどは、遠慮なく、お問い合わせ、コメント、Twitterにてご連絡ください。
最後までお読みいただきありがとうございました。