develooper Front page | perl.beginners | Postings from April 2010

Re: Perl rounding errors?

Thread Previous | Thread Next
From:
Shlomi Fish
Date:
April 26, 2010 04:05
Subject:
Re: Perl rounding errors?
Message ID:
201004261405.17057.shlomif@iglu.org.il
Hi Rob,

On Monday 26 Apr 2010 13:38:07 Rob Coops wrote:
> Hi list,
> 
> I am just wondering if I sumbled upon an error in perl an error in my logic
> or somehtign else see the below perl one liners
> 
> $ perl -e '$n = 0.945; $r = sprintf("%.2f", $n); print "$r\n";'
> 0.94
> 
> $ perl -e '$n = 0.9451; $r = sprintf("%.2f", $n); print "$r\n";'
> 0.95
> 
> $ perl -e '$n = 0.9450; $r = sprintf("%.2f", $n); print "$r\n";'
> 0.94
> 
> $ perl -e '$n = 0.94500; $r = sprintf("%.2f", $n); print "$r\n";'
> 0.94
> 
> $ perl -e '$n = 0.945001; $r = sprintf("%.2f", $n); print "$r\n";'
> 0.95
> 
> Now I expected perl to round the number: 0.945 to 0.95 and not to 0.94 like
> it is doing. I have no idea why it is doing this but I sure don't like it.
> The problem is I have to do some VAT calculations on thousands of invoices
> and invoice elements. I found that in rare cases I'm of by 1 cent or even 3
> cents if there are lots of elements. Going over the logic I ran into this
> problem.
> 
> Cany anyone advise me how to deal with this as I need to find a way to
> round correctly in all cases not just in cases where Perl decides it is a
> good idea to do so. :-)
> 

The problem is likely caused by the fact that floating-point numbers in most 
modern computers are represented by using binary digits (and binary fractions) 
instead of decimal ones. So there may be rounding errors. As a result, it is 
not advisable to use the regular floating-point numbers for dealing with 
monetary values. Some of the options you may wish to consider instead are:

1. Use a rational library for computation such as Math::BigRat.

2. Use a binary-coded-decimal (BCD) system. Last time I investigated I 
couldn't find one for Perl, though , and I've misplaced the link to the 
downloadable software library at IBM for that. (Though Python has something 
like that in pure-Python)

3. Work always in the smallest unit - cents or whatever.

Regards,

	Shlomi Fish

> Regards,
> 
> Rob

-- 
-----------------------------------------------------------------
Shlomi Fish       http://www.shlomifish.org/
My Aphorisms - http://www.shlomifish.org/humour.html

God considered inflicting XSLT as the tenth plague of Egypt, but then
decided against it because he thought it would be too evil.

Please reply to list if it's a mailing list post - http://shlom.in/reply .

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About