日向夏特殊応援部隊

俺様向けメモ

四捨五入について

んー、これバカっぽぃネタですけども。

  1. Perlメモ
  2. Math::Round

ちょっとカスタムでサブルーチンを定義するのもなんかこそばゆい。
従って後者の場合。

Math::Round::nearestを使う場合

小数点第2位を四捨五入して小数点第1位まで丸めたい場合、Math::Roundを使うと、

$ perl -MMath::Round -e 'for (my $i = 0.01; $i <= 0.1; $i += 0.01) { my $j = 1.0 + $i; printf("%.2f -> %.2f\n", $j, Math::Round::nearest(.1, $j)) }'
1.01 -> 1.00
1.02 -> 1.00
1.03 -> 1.00
1.04 -> 1.00
1.05 -> 1.10
1.06 -> 1.10
1.07 -> 1.10
1.08 -> 1.10
1.09 -> 1.10
1.10 -> 1.10

うん、きちんと四捨五入されてますね。

printfのみ

ちなみにsprintf("%.1f", 1.05)でも似たようなroundが出来ます。

$ perl -e 'for (my $i = 0.01; $i <= 0.1; $i += 0.01) { my $j = 1.0 + $i; printf("%.2f -> %.2f\n", $j, sprintf("%.1f", $j)); }';
1.01 -> 1.00
1.02 -> 1.00
1.03 -> 1.00
1.04 -> 1.00
1.05 -> 1.10
1.06 -> 1.10
1.07 -> 1.10
1.08 -> 1.10
1.09 -> 1.10
1.10 -> 1.10

有効なソースは見つからないんだけど、隣のだにたん*1の環境では四捨五入にはならなかった。

もうちょっと詳しく(追記)

どうも演算の仕方によっては誤った結果が返ってくる場合があるみたいです。
上のforループでの演算と直接例えば1.14, 1.15とかを一個ずつprintfでroundすると、

$ perl -e 'my $n = 1.14; printf("%.1f\n", $n);'                                                     1.1
$ perl -e 'my $n = 1.15; printf("%.1f\n", $n);'                                                     1.1

ってなります。

これは次のような比較をすると分かるかな。

$ perl -e 'printf("%.20f, %.20f\n", 1.15, 1.10 + 0.05);'
1.14999999999999991118, 1.15000000000000013323