Granted this a bit off-topic to Perl & Mac OS X, but it is just too fun a question to 
pass up during lunch!

Below is some code on you might resolve your problem...or at least is fun to run 
(okay, I think it is fun to run).  In the end, it may be too convulated an example of 
an alternative means.  It is nonetheless illustrative of how you might approach this 
depending on your needs.

Basically, using map() (not at all necessary but it makes for compact (arguably easier 
to read) code).  The inner map() multiples each value by 10^N where N represents our 
precision.  E.g. 1.655 -> 165.5.  We then use int() to turn this into 165.  The next 
(outer) map() then divides through by 10^N, or 165 -> 1.65.  When you print this you 
will get the right answer.  It does not round per say, but you do get around issues of 
sprintf() doing unwanted/unpredictable rounding with floating-point precision.

There are certainly more robust ways of doing rounding.  And typ. I think it best to 
write your own...there are tons of examples on the web.  If you can read FORTRAN or C 
then you have even more than just Perl's examples to look at, too.

Good luck and have fun!

<code language="Perl">
#!/usr/bin/perl -w 
use strict;
# our values we would like to truncate (note, I said truncate, not round)
my @values = (1.655, 1.755);
# how much precision we would like to have
my $precision = 2;
# a referenced sub to make our like a little easier
my $printTrunct = sub { "\n".sprintf("%.${precision}f",$_) };
# first, print out our numbers using sprint() 
print &$printTrunct($_) foreach @values;
# next, use alternative means whereby we multiple my the 
# order of magnitude.
# use int() to get rid of the unwanted trailing numbers
# and then divide through by again the order of magnitude (base 10)
# we use maps in a fun manner, too! Yeah for map()!!!  How many times do you
# get to see nested maps?
print &$printTrunct($_) foreach (
        map(
                (
                        ($_/(10**$precision)), 
                        map(
                                int($_*(10**$precision)),
                                @values
                        )                
                )
        )
);
exit;
</code>

On Monday, October 13, 2003, at 11:56AM, Dan Sugalski <[EMAIL PROTECTED]> wrote:

>On Mon, 13 Oct 2003, Bill Stephenson wrote:
>
>> I've got a script that takes numbers similar to those below and then rounds
>> them and adds them together using code similar to what is below.
>[snip]
>> The code above prints this result (system 10.1.5, perl 5.6.0):
>>
>>     1.66, 1.75
>>
>> But shouldn't it be:
>>
>>     1.66, 1.76
>>
>> or:
>>
>>     1.65, 1.75
>>
>> I'm no math wizard, so if someone could please take the time and tell what
>> I'm missing here I would very much appreciate it!
>
>Welcome to the wonderful world of inexact representations.
>
>You're getting bitten by some fundamental issues with floating point
>representations of numbers. Floating point fractions are base 2, so they
>can't properly represent anything that's not base 2. (And, since our
>decimal fractions are base 10, that can be a lot of 'em)
>
>There's more explanation in the perl faq, along with some workarounds.
>
>                               Dan
>
>
 

--
Ward W. Vuillemot
[EMAIL PROTECTED]

Reply via email to