http://www.perlmonks.org?node_id=239188

MZSanford has asked for the wisdom of the Perl Monks concerning the following question:

The following code does not work as i would expect. I was wondering if anyone knows why 1.15*100 acts diffrent under int(). My original code is below :

use strict; my $key = 12345; my @amn = (3.95,1.15); my ($s,$s2); for (@amn) { $s += int($_*100); $s2 += $_*100; } print "Scalar 1 : $s\n"; print "Scalar 2 : $s2\n";

This prints :

Scalar 1 : 509 Scalar 2 : 510

This was tested on

A shorter version of this would be :

perl -e 'print 1.15*100,"\n",int(1.15*100),"\n"'

I know NV conversion is always open to a fudge-factor, but this seems pretty tame to be effected by that. Any help is appriciated.


from the frivolous to the serious

Replies are listed 'Best First'.
Re: NV/IV Bug ?
by Elian (Parson) on Feb 27, 2003 at 18:42 UTC
    Why are you thinking that it's surprising? Floats can't represent anything that isn't a fraction of two (1/2, 1/4, 1/8, and so on) so since you've chosen a number that's unrepresentable, you're going to get bad results.

    Just one more good reason to not use IEEE floating point numbers to represent money...

      good point. Hence the *100 being used on the string which was read from a file.
      from the frivolous to the serious
Re: NV/IV Bug ? (a fix)
by tye (Sage) on Feb 27, 2003 at 19:35 UTC

    Use int( $_*100 + 0.5 ) instead of int($_*100). (I saw lots of explanations posted but no solutions.)

                    - tye
Re: NV/IV Bug ?
by IlyaM (Parson) on Feb 27, 2003 at 18:47 UTC
Re: NV/IV Bug ?
by extremely (Priest) on Feb 27, 2003 at 18:48 UTC
    1.15 in binary is... ooops, an infinite series. There is special magic in place for what is basically 1.1499999999999 when multiplied and printed. But when you you force to int(), you dodge that magic and get the proper truncated value.

    --
    $you = new YOU;
    honk() if $you->love(perl)

      Thanks, that explains. Inconsistant (by design) Magic application. If neither worked, i would not have posted ... i do understand floating point numbers, but the inconsistancy was bothering me. Thanks again.
      from the frivolous to the serious
Re: NV/IV Bug ?
by Steve_p (Priest) on Feb 27, 2003 at 19:18 UTC

    int() always rounds down. In cases where you are working with floating-points, the precision may not be what you expect. So, to paraphase perldoc -f int, your 395 and 115 may look more like 394.99999943242 or 114.999999523523. In either case, the decimal portion is truncated off. Instead, sprintf, printf, POSIX::floor, or POSIX::ceil may be better options for what you want to do.

Re: NV/IV Bug ?
by Anonymous Monk on Feb 27, 2003 at 18:40 UTC
    int make int from number int (5)=5 int (5.9)=5 thats why