HOMEUP

round関数に関しての調査

Common Lispの数値関数に関してページを作っていたのですがCommon Lispの丸め、roundは偶数丸めと決まっていました。Rubyでは偶数じゃない丸め(四捨五入)でした。

偶数丸め(JIS丸めともいう)っていうのは丸めようとする数が0と1の間の中間の0.5の場合、偶数、つまり0に丸めるというものです。(JIS規格では偶数丸めを採用しているとのこと)

偶数丸めを使うと誤差が少なくなるらしいです。

例えば

  1. nに0.5を足して丸める
  2. 丸めたものをnとする
  3. nから0.5を引いて丸める
  4. 丸めたものをnとする

を、繰り返します。nの初期値が0の時に偶数丸めじゃない(四捨五入)の場合、

  1. 0 + 0.5 → 0.5 → 1
  2. 1 - 0.5 → 0.5 → 1
  3. 1 + 0.5 → 1.5 → 2
  4. 2 - 0.5 → 1.5 → 2
  5. 2 + 0.5 → 2.5 → 3
  6. 2 - 0.5 → 2.5 → 3

となってnがどんどん増えていく \(^o^)/オワター

でも偶数丸めだと

  1. 0 + 0.5 → 0.5 → 0
  2. 0 - 0.5 → -0.5 → 0
  3. 0 + 0.5 → 0.5 → 0
  4. 0 - 0.5 → -0.5 → 0
  5. 0 + 0.5 → 0.5 → 0
  6. 0 - 0.5 → -0.5 → 0

と、なります。

ちょっと気になったので手元で使えるプログラミング言語でやってみました。

CLisp(Common Lisp)(round 0.5)0
(round 1.5)2
SBCL(Common Lisp)(round 0.5)0
(round 1.5)2
Gauche(Scheme)(round 0.5)0.0
(round 1.5)2.0
ghc(Haskell)round(0.5)0
round(1.5)2
Ruby(0.5).round1
(1.5).round2
Pythonround(0.5)1.0
round(1.5)2.0
gcc(C)round(0.5)1.0
round(1.5)2.0
MySQLround(0.5)1
round(1.5)2
OpenJDK1.6(Java)Math.round(0.5)1
Math.round(1.5)2

Common Lispは仕様でroundは偶数丸めをするように決まっています。

Rubyは四捨五入。

多分Javaも?

他の言語は調べてないのですがいわゆる関数型は偶数丸めをするみたいですね。

MySQLのデータベースを関数型言語でアクセスするときにハマりそうですね。SELECT ROUND(hogehoge)とするか、SELECT hogehogeしたものをroundするかで結果が変わる…φ(-_-) メモっとこ

HOMEUP