四捨五入を行う
四捨五入を行うには、sprintf関数を使用します。フォーマット指定を、有効桁を指定して四捨五入したい場合は"%.3g"や"%.5g"のように指定し、小数点以下のある桁で四捨五入したい場合は"%.3f"や"%.5f"のように指定します。
# 小数点以下の桁数で指定。 sprintf("%.1f", $num1); # 有効桁数で指定。 sprintf("%.1g", $num1);
四捨五入を行うには、sprintf関数を使用します。"%.1f"という書式指定は、浮動小数点を小数点第1までに丸めるという書式指定です。小数点第2位が四捨五入されます。
有効桁数を指定して四捨五入を行いたい場合は、"%.1g"のように指定します。たとえば37.48を、"%.3g"で書式指定をすると、37.5という数値が得られます。
四捨五入の注意点
my $num2 = 0.725; my $num2_round = sprintf("%.2f", $num2);
数値リテラルで表現した0.725は、内部的には0.725ではありません。2進数で表現でいない数値は、内部的に必ず誤差が発生し(わたしの環境では)近似値 0.72499999999999998 として扱われています。
これを小数点第3位で四捨五入すると0.724になります。これは期待した結果になりません。
sprintfによる四捨五入は正しくない
sprintfによる四捨五入は行うべきではないという指摘がありました。
おっしゃられているように正確に四捨五入をしたい場合はsprintfを使うべきではありません。sprintfによる四捨五入はたいていの場合はうまくいきますが、上記のような例外があります。
もっと正確に四捨五入をしたい場合にMath::Round::nearestというCPANモジュールがあるそうです。
end0tknrさん、ご指摘ありがとうございます。
サンプルプログラム
四捨五入を行うサンプルです。
use strict; use warnings; my $num1 = 100.47; print "(1)四捨五入を行う。\n"; my $num1_round = sprintf("%.1f", $num1); print "$num1を小数点第2位で四捨五入すると${num1_round}になります。\n\n"; print "(2)四捨五入の注意点\n"; my $num2 = 0.725; # 0.73にはならない。 my $num2_round = sprintf("%.2f", $num2); print "0.725を小数点第3位で丸めると${num2_round}になります\n\n"; printf("内部的には%.30fという数であることが原因\n" . $num2);