Pythonのround関数で数値の小数点を偶数の丸めのイメージ画像

Pythonのround関数で数値の小数点を偶数の丸め

  • 公開日:2018/10/27
  • 更新日:2018/10/27
  • 投稿者:n bit

 Pythonで浮動小数点の小数部を丸めて整数化したいときに利用する組み込み関数『round関数』について解説。四捨五入ではなく偶数の丸め処理を行うので注意。偶数の丸めについては詳しくわかりやすいよう実例付きで説明します。

  • Python

この記事は約 分で読めます。(文字)

round関数とは

round関数とはPythonで浮動小数点数の小数部を指定の桁数に丸める組み込み関数です。

たまに四捨五入する関数として勘違いされていますがPythonで四捨五入を行うには別のモジュールを必要としround関数では『偶数の丸め』を行っています。

偶数の丸め

「偶数の丸め」とは聞きなれない言葉かと思いますがその内容は別に難しいものではありません。偶数の丸めのルールは3つです。

  • 小数部が0.5より小さい場合は切り捨て
  • 小数部が0.5より大きい場合は切り上げ
  • 小数部が0.5の場合は結果が偶数になる方へ処理

言葉で書くと少しややこしいので実例を入れて説明していきましょう。

例えば「1.4」に偶数の丸め処理を行う場合は「小数部が0.5より小さい」ので切り捨てられ「1」となります。

次に「1.6」に偶数の丸め処理を行う場合は「小数部が0.5よりも大きい」ので切り上げられ「2」となります。

最後に「1.5」に偶数の丸め処理を行う場合は「少数分がちょうど0.5」で切り下げた場合は「1」、切り上げた場合は「2」となります。この場合、結果が偶数となるのは「2」の方ですので切り上げて処理します。

round関数の使い方

実際に数値を入力して結果を確認した方が分かりやすいと思いますので早速round関数を使ってみましょう。round関数は引数に偶数の丸めを行いたい浮動小数点数を指定します。

round(浮動小数点数)

round関数を使って実際に浮動小数点数へ偶数の丸めをしてみましょう。

round関数で浮動小数点数を整数に偶数の丸め

round関数で浮動小数点数を整数に偶数の丸めしてみます。返された値をprint関数で出力しました。round関数で最も基本的な使い方です。

x = round(12.4)

print(x)

x = round(12.5)
print(x)

x = round(12.6)
print(x)

出力結果

12

12
13

12.5が四捨五入の「13」ではなく偶数の丸めの「12」になっていることが確認できます。

それでは小数部の桁数が増えた場合はどうなるでしょうか。「12.53」で考えてみましょう。

x = round(12.43)

print(x)

x = round(12.53)
print(x)

x = round(12.63)
print(x)

出力結果

12

13
13

今度は「12」ではなく「13」になりましたね。

偶数の丸めについてもう少し詳しく説明すると実は「入力値に最も近い整数を返す」、そして「入力値に最も近い整数が2つあった場合は偶数側の整数を返す」処理を行っています。

12.4、12.5、12.6に近い整数は「12」または「13」です。

  • 12.4と12の差は「0.4」、12.4と13の差は「0.6」ですので入力値に最も近い整数は「12」。
  • 12.6と12の差は「0.6」、12.6と13の差は「0.4」ですので入力値に最も近い整数は「13」。
  • 12.5と12の差は「0.5」、12.5と13の差も「0.5」ですので入力値に最も近い整数が2つ。その場合偶数側の整数は「12」。

ここまで理解できれば12.53が「13」になる理由もわかりますよね。

12.53と12の差は「0.53」、12.53と13の差は「0.47」ですので入力値に最も近い整数は「13」。12.5とは違い「0.03」が計算に含まれる結果わずかではありますが差が生まれるため最も近い整数が返されます。

そのため12.53の偶数の丸めは「13」になるのです。

round関数で浮動小数点数を指定の桁数で偶数の丸め

次は浮動小数点数を指定の桁数で偶数の丸めを行う方法です。偶数の丸めを行う桁をコントロールしたい場合は第二引数に丸める桁数を指定することで変更できます。

round(浮動小数点数, 丸める桁数)

浮動小数点数を小数部一桁目で偶数の丸めしてみます。

x = round(12.54, 1)

print(x)

x = round(12.55, 1)
print(x)

x = round(12.56, 1)
print(x)

出力結果

12.5

12.6
12.6

出力結果を見て疑問に感じた方もおられるかもしれませんが、今回は小数部一桁目で偶数の丸めを行うためこのような結果になります。

12.55と12.5の差は「0.05」、12.55と12.6の差も「0.05」ですので入力値に最も近い整数が2つ。そのため偶数側で「12.6」が正しい結果です。

浮動小数点数の2進数問題

人間は数値を10進数で扱いますがコンピュータは2進数で扱っています。多くの少数は残念ながら2進数で正確に表すことができません。そのため10進数の数値に近い近似値で表現されています。

そのためPythonの公式ドキュメントにも注釈があるように予想通りの結果にならない場合があります。

Note

注釈:浮動小数点数に対する round() の振る舞いは意外なものかもしれません: 例えば、 round(2.675, 2) は予想通りの 2.68 ではなく 2.67 を与えます。これはバグではありません: これはほとんどの小数が浮動小数点数で正確に表せないことの結果です。

出典:2. 組み込み関数 — Python 3.6.5 ドキュメント

詳細情報:15. 浮動小数点演算、その問題と制限 — Python 3.6.5 ドキュメント

しかし実際使用する上ではこれらがエラーとなって問題になるようなケースはほとんどありません。(2**53 分の 1)

今日のdot

round関数は四捨五入ではなく浮動小数点数の偶数の丸めを行う組み込み関数です。

会計に関するアプリケーションや非常に高い精度の計算が求められる状況でPythonに浮動小数点数や四捨五入処理を含めた正確な演算を行いたい場合はdecimal モジュールやfractions モジュールを利用して行うと良いでしょう。