読者です 読者をやめる 読者になる 読者になる

そんな今日この頃でして、、、

コード書いたり映画みたり。努力は苦手だから「楽しいこと」を探していきたい。

今日踏んだ落とし穴、printfでの小数の桁揃えに注意

学生の頃に地方システム屋へのインターンで「こんな地味で面白くもないこと仕事にしたくないぜ!」と感じてウェブ界隈に就職したのに、なぜか今現在は帳票システムめいた案件に関わってるっていうインガオホー。

さて、金回り・契約回りの数値となると数字の正確さはもちろん表記まで色々要求がシビアになったくるわけだが、今日踏んだのはprintfによる小数点の桁揃えでの問題。


数値から整数部分と取り出すという要件の場合、一番大雑把にやるならint($num)という手があるが、これは厳密には非推奨。

$ perldoc -f int
       int     Returns the integer portion of EXPR.  If EXPR is omitted, uses
               $_.  You should not use this function for rounding: one because
               it truncates towards 0, and two because machine representations
               of floating-point numbers can sometimes produce
               counterintuitive results.  For example, "int(-6.725/0.025)"
               produces -268 rather than the correct -269; that's because it's
               really more like -268.99999999999994315658 instead.  Usually,
               the "sprintf", "printf", or the "POSIX::floor" and
               "POSIX::ceil" functions will serve you better than will int().

曰く、sprintfとかprintfとか、POSIX::floorなりPOSIX::ceilあたりを使えよとのこと。

use POSIX qw/floor/;とか書くのも面倒くさいので、僕は$num = sprintf "%d", $num;の方を好んで使う。


さて今回は同じノリで値を小数点第二位で切りそろえるという要件に対しsprintf "%.2f", $num;と実装したわけだが、これがちょっとうまく行かなかった。

$ perl -e 'printf "%.2f", 123.456;'
123.46

どうやら%.Xf単純に桁で切りそろえてくれるわけじゃないらしい。

ちなみに切り上げとか四捨五入とも挙動は違うので注意。

perl -e 'printf "%.2f", 123.455;'
123.45

どうやら正攻法で100かけて整形して100で割る、みたいなことをしなくちゃいけなそう。

perl -e 'print(sprintf("%d",123.456*100)/100)'
123.45

もう21世紀なんだし何か他にスマートな書き方は無いのかなと探してみたけど、ちょっと見当たらなかった。

初めてのPerl 第6版

初めてのPerl 第6版

自分用メモ

Mojo::Liteのxslate_rendererでヘルパー使うときの記述↓

#pl側
use Text::Xslate qw/html_builder/;
plugin 'xslate_renderer' => {
  template_options => {
    function => {
      test => sub{
        return html_builder {
          my $html = shift;
          my $tag = $html."test";
          return $tag;
        };
     },
  }
};
#tx側
:"a"|test(); #=> atest
  1. template_options内にfunctionとして記述
  2. html_builderで返す