Perl入門ゼミ

テキスト処理、Linuxサーバー管理、Web開発ならPerl
  1. Perl
  2. 数値
  3. here

四捨五入を行う

四捨五入を行うには、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による四捨五入は正しくない

perlで四捨五入(end0tknrのkipple)

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);
Giblog