Article 7672 of comp.lang.perl:
Xref: feenix.metronet.com comp.lang.perl:7672
Path: feenix.metronet.com!news.utdallas.edu!hermes.chpc.utexas.edu!cs.utexas.edu!uwm.edu!news.moneng.mei.com!howland.reston.ans.net!agate!ames!koriel!sh.wide!wnoc-tyo-news!scslwide!wsgw!headgw!cvgw3!tshiono
From: [email protected] (Toru SHIONO)
Newsgroups: comp.lang.perl
Subject: Re: can't round floats with int()
Message-ID: <[email protected]>
Date: 6 Nov 93 07:25:50 GMT
References: <[email protected]> <[email protected]> <[email protected]> <[email protected]>
Sender: [email protected] (Usenet News System)
Organization: Sony Corporation, Tokyo, Japan
Lines: 60
Nntp-Posting-Host: aquarius
X-Newsreader: prn Ver 1.07
In-reply-to: [email protected]'s message of 5 Nov 93 16:19:45 GMT

In article <[email protected]>
       [email protected] (David S. McCormick) writes:

:I have tried to create a perl4 subroutine that rounds floats at
:a given decimal place, but I always get back the original,
:unrounded value. Any help appreciated. Program below:
:
:$endl = "\n";
:$in = 0.0899999999999998579;
:$out = &round_up_to_exponent($in, -2);
:
: print $in, " ", $out, $endl;
:
:# rounds the value _UP_ to appropriate base 10 value,
:# eg, (8.056, -2) rounds 8.056 -> 8.06
:# usage: &round_up_to_exponent(value, exponent);
:sub round_up_to_exponent {
:       local($ival);
:       local ($val, $exponent) = @_;
:       print $val, $endl;
:       $val /= 10**($exponent);
:       print $val, $endl;
:       $ival = int($val + 0.5);
:       print $ival, $endl;
:       $ival *= 10**($exponent);
:       print $ival, $endl;
:       $ival;
:}
:
:the results of the above are:
:0.0899999999999998579
:8.99999999999998579
:9
:0.08999999999999999666
:0.0899999999999998579 0.08999999999999999666


Real values are internally converted to a binary representation.
Fractional values tend to be of an infinite length, and the limited
wordlength causes a truncation error.

Even if you just say:

       $val = 0.09;
       print $val;

The result may be not what you expect.
It will be better to use sprintf() to round values:

sub round_up_to_exponent {
   local ($val, $exp) = @_;
   sprintf("\%.${exp}f", $val);
}
$in = 0.0899999999999998579;
$out = &round_up_to_exponent($in, 2);   # the exponent negated just for
                                       # convenience

Setting $# to some appropriate format may also help.
--
Toru "devil-may-care" Shiono          Sony Corporation, JAPAN