Perl の数値表示

さてここで、これまでの2つの出力結果を並べて見ましょう。

1.66666666666667 は 2 を 3 で割って1を足した結果です。
0.5 は 2 を 3 足す 1 で割った結果です。
1番目は「1.66666666666666....」じゃないんですか? また、何で2番目は「0.50000000000000」じゃないんでしょうね?

実は、Perl は数値を「浮動小数点数」という形式で保存しています。それを、出力の時に「よしなに」変換してくれるのです。

Perl の数値自動変換の確認

Perl が、出力される値の通りに数値を保存している訳ではない事を、プログラムで確かめてみましょう。
my $kekka1 = 2 / 3 + 1;
my $kekka2 = 1 / 3;
my $kekka3 = $kekka1 - $kekka2;

print "kekka1 は $kekka1 です。
";
print "kekka2 は $kekka2 です。
";
print "kekka3 は $kekka3 です。
";
結果出力は以下のようになります。
kekka1 は 1.66666666666667 です。
kekka2 は 0.333333333333333 です。
kekka3 は 1.33333333333333 です。
kekka3 が、単純に kekka1 の「1.66666666666667」から kekka2 の「0.333333333333333」を引いているのではない事が分かりますね。

Perl は様々な計算を行った後で最後に、表示がなるべく短くなるように出力を調整してくれます。

Perl の有効数字

しかし、Perl がいかに気をまわしてくれても「0.5」ではなく「0.50」と表示したい場合がありますね。その場合はどうすればいいんでしょうか?

試しに「0.50」を代入してみましょう。

Perl で有効数字を指定する 1
my $shousuu1 = 0.5;
my $shousuu2 = 0.50;

print "shousuu1 は $shousuu1 です。
";
print "shousuu2 は $shousuu2 です。
";

結果は...
shousuu1 は 0.5 です。
shousuu2 は 0.5 です。
おや。だめですね。この場合、自動調整してくれる Perl の気遣いが的外れです。

Perl で有効数字を指定する 2

ではこれならどうでしょう。Perl は表示したい文字は「"」で囲っておけばいいので、初めからそれを指定してしまえばいいのです。
my $shousuu1 = 0.5;
my $shousuu2 = 0.50;
my $shousuu3 = "0.50";

print "shousuu1 は $shousuu1 です。
";
print "shousuu2 は $shousuu2 です。
";
print "shousuu3 は $shousuu3 です。
";
結果は
shousuu1 は 0.5 です。
shousuu2 は 0.5 です。
shousuu3 は 0.50 です。
お、これなら行けそうですね。調子づいて、掛け算も練習しましょう。

Perl で有効数字を指定する 3

my $shousuu3 = "0.50";
my $shousuu4 = $shousuu3 * 3;

print "shousuu3 は $shousuu3 です。
";
print "shousuu4 は $shousuu4 です。
";
結果は
shousuu3 は 0.50 です。
shousuu4 は 1.5 です。
あれ...。計算した後が「1.50」にはなりませんね。

Perl は、文字列に対して計算を行った時には逆に「よしなに」数値に変換してしまうのです。

Perl の数値の出力桁数調整

このため、Perlの桁数を指定して表示したい場合は sprintf という関数を使います。

sprintf を使った桁数調整
my $shousuu3 = "0.50";
my $shousuu4 = $shousuu3 * 3;
my $shousuu5 = sprintf('%.2f', $shousuu4);

print "shousuu3 は $shousuu3 です。
";
print "shousuu4 は $shousuu4 です。
";
print "shousuu5 は $shousuu5 です。
";
shousuu3 は 0.50 です。
shousuu4 は 1.5 です。
shousuu5 は 1.50 です。
これで期待通りに小数点以下2桁で表示できましたね。

sprintf を使って数字を丸める

では、先ほどの割り算も少し結果が長すぎたので同じように小数点以下2桁で表示してみましょう。
my $seisuu = 2;
my $kekka = $seisuu / 3 + 1;
my $shousuu2keta = sprintf('%.2f', $kekka);

print "kekka は $kekka です。
";
print "shousuu2keta は $shousuu2keta です。
";
kekka は 1.66666666666667 です。
shousuu2keta は 1.67 です。
おお、うまくいきました。sprintf は指定桁数に収まるように値を四捨五入してくれる事も分かりましたね。

sprintf の書式

sprintf に指定している「'%.2f'」の部分は、「2」の部分が小数点以下の桁数を指定しています。残りの部分は数値を表示する時の固定ですので、このまま覚えてしまいましょう。

>>次は:プログラムの改善