Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re: strange arithmetic results

by arturo (Vicar)
on Sep 25, 2001 at 17:05 UTC ( [id://114523]=note: print w/replies, xml ) Need Help??


in reply to strange arithmetic results

One workaround is to *impose* precision: here, you want equality up to the first two decimal places, so you could multiply your numbers by 100 and take the int() value of them to compare. Here's a subroutine:

sub cmp_dollar { my ($c, $d) = map { int( $_ * 100 ) } @_; $c == $d; }

This oughta deal with the trailing \n issue, too, as that will be ignored by the automagic string-number conversion.

perl -e 'print "How sweet does a rose smell? "; chomp ($n = <STDIN>); +$rose = "smells sweet to degree $n"; *other_name = *rose; print "$oth +er_name\n"'

Replies are listed 'Best First'.
Re: Re: strange arithmetic results
by tommyw (Hermit) on Sep 25, 2001 at 17:24 UTC

    Actually, that's not the way to deal with it: you want to get your data values converted into cents (and error correct at this point) very early, and then work in cents (or tenths of cents) throughout, rather than holding them in dollars and multiplying by 100 at odd moments to do comparisons.

    The reason this is a problem is that, as with the fraction 1/3 in decimal, 1/10, or 1/100 does not have a finite representation in binary. So the end of the value gets chopped off. Then, when it's multiplied back up, that chopped piece is not reinstated. (Exactly the same way that 1/3 * 3 on a calculator can give you the answer 0.99999)

    So if you've got two amounts which differ by very small fractions of a cent, and multiply them both by 100, you multiply the error by 100. That might be enough to make int return different answers.

    sub dollars_to_cents { map { int ($_*100+0.5) } @_; } $dollars=<STDIN> $cents=dollars_to_cents($dollars)
    would be better way of dealing with the conversion.

    Change the multiplier in the function, if you wish more accuracy (so 1000 if you wish to deal in tenths of a cent). The addition of 0.5 brings the answer to the closest cent, to allow for the possible rounding error. It doesn't need changing

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://114523]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (2)
As of 2024-04-19 19:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found