end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転しました

perlの四捨五入は、IEEE754 ?に影響されるので、一旦、整数化しましょう

Math::Round::nearest を使ったとしても、そもそもperl浮動小数点はIEEE754による実装なので、四捨五入は正確ではありません。

次のような感じで、一旦、整数化しましょう

#!/usr/local/bin/perl
use strict;
use Math::Round qw/nearest/;

my $MAGNIFICATION = 1000;
main();

sub main {

    for my $vals
        ([0.01, 144.534, 144.53], [0.01, 144.535, 144.54],
         [0.01, 144.536, 144.54], [0.01, 144.545, 144.55],
         [0.01, 144.555, 144.56], [0.01, 144.565, 144.57],
         [0.01, 144.575, 144.58], [0.01, 144.585, 144.59],
         [1   , 144.500, 145   ], [1   , 144.499, 144   ]){


        my $round_val =
            Math::Round::nearest($vals->[0]*$MAGNIFICATION , $vals->[1]*$MAGNIFICATION )
                / $MAGNIFICATION;
        # my $round_val = Math::Round::nearest($vals->[0],$vals->[1]);

        if( $round_val == $vals->[2] ){
            print "OK Round $vals->[0],$vals->[1]) = $round_val\n";
        } else {
            print "NG Round $vals->[0],$vals->[1]) = $round_val != $vals->[2]\n";
        }
    }

}

↑こうかくと、↓このように正解を算出できます

]$ ./foo.pl 
OK Round 0.01,144.534) = 144.53
OK Round 0.01,144.535) = 144.54
OK Round 0.01,144.536) = 144.54
OK Round 0.01,144.545) = 144.55
OK Round 0.01,144.555) = 144.56
OK Round 0.01,144.565) = 144.57
OK Round 0.01,144.575) = 144.58
OK Round 0.01,144.585) = 144.59
OK Round 1,144.5) = 145
OK Round 1,144.499) = 144
[endo@cent6 tmp]$

浮動小数点の四捨五入を正しく算出するモジュールがあるかも知れませんが、上記で十分かと思います