50
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

python3の四捨五入でハマったのでメモ

python2の四捨五入

四捨五入にはround()を使います。

>>> round(1.5)
2.0
>>> round(2.5)
3.0
>>> round(10.0/3, 0)
3.0

一般的な四捨五入ですね。

python3の四捨五入

>>> round(1.5)
2
>>> round(2.5)
2
>>> round(10.0/3, 0)
3.0

結果が異なる。

なにこれ

以下、Wikipedia先生より

端数処理

最近接偶数への丸め[編集]
最近接偶数への丸め (round to the nearest even; RN) は、端数が0.5より小さいなら切り捨て、端数が0.5より大きいならは切り上げ、端数がちょうど0.5なら切り捨てと切り上げのうち結果が偶数となる方へ丸める。JIS Z 8401で規則Aとして定められていて、規則B(四捨五入)より「望ましい」とされている。
四捨五入ではバイアスが発生する、端数0.5のデータが有限割合で存在する場合でも、バイアスがないのが特徴であり、多数足し合わせても丸め誤差が特定の側に偏って累積することがない(偶数+0.5は現れるが奇数+0.5は現れない、といったような特徴があるデータであれば、やはりバイアスはあらわれる)。

とのこと。

解決策

python3のroundをpython2と同様にするための、my_round関数を作ります。

import math
def my_round(x, d=0):
p = 10 ** d
return float(math.floor((x * p) + math.copysign(0.5, x)))/p

こんな感じになるらしい。

(09/03/2016 追記 shiracamusさんありがとうございます)
lambdaを使えばもっと簡単になる。

round=lambda x:(x*2+1)//2
round(1.5)
2.0
round(2.5)
3.0
round(10.0/3.0)
3.0

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
50
Help us understand the problem. What are the problem?