A classical example:

$ perl -le 'print "Wrong " if 19.08 + 2.01 != 21.09;' Wrong

You would most probably get the same type of result with Python, Ruby, C, Java, Fortran or what have you. The problem is not Perl, but the architecture of almost all current computers. The problem has to do with differences between numbers (the mathematical concept) and numerals (their representation on a computer). Just as 1/3 has a never ending 0.333333... representation in decimal notation, some numbers deemed to be simple in decimal notation have a never ending representation in the internal binary format of most computers.

To find out the difference between 19.08 + 2.01 and 21.09, try this:

$ perl -le 'print 21.09 - (19.08 + 2.01), "\n";' 3.5527136788005e-15

3.5527136788005e-15 is admitedly a very small number, but it is not 0. The classical method for comparing floating point notation numbers is to check if the absolute value of their difference is smaller than a very small number usually called epsilon (perhaps something like 1e-14). If the difference is smaller than epsilon, then the number are considered to be the same. For example:

$ perl -le '$epsilon = 1e-14; print "Wrong " if abs (19.08 + 2.01 - 21 +.09) > $epsilon;' $ perl -le '$epsilon = 1e-14; print "Wrong " if abs (19.08 + 2.02 - 21 +.09) > $epsilon;' Wrong

In the first case, the difference is about 3e-15, so smaller than epsilon, I do not get an error; in the second case, the difference is about 0.01, much larger that epsilon, I get the "wrong" message.

To tell the truth, there is another source of errors, which is perhaps more important in your case: the summation of rounding errors. A very classical problem: make an invoice of a few lines, with the tax free amount in the first column, and the tax-included amount in the second comumn, for a few items. Then calculate the total tax free amount, apply the common tax rate to that total mount, chances are high that the total tax-included amount calculated this way will not be the same as the sum of the tax-included items. The company for which I am a consultant spent several hundred thousand euros on an IT project to try to get rid of these rounding errors (making all calculations with 5 decimal digits), the situation is now much better, but you just can't get rid of all discrepancies, so that the invoice has a sentence somewhere saying that the tax amount for individual lines are only given as an estimate, only the last total line contains real amounts.

BTW, using the bigint module seems to solve the problem:

$ perl -le 'use bigint; print "Wrong " if 19.08 + 2.01 != 21.09;' $ perl -le 'use bigint; print 21.09 - (19.08 + 2.01), "\n";' 0

I am not sure, though, that this works in all cases.

Update: Oops, thanks choroba, the above (crossed part) is obviously silly. Yes, bignum should probably help much better. But I haven't tested yet.


In reply to Re: precision problem ? by Laurent_R
in thread precision problem ? by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.