jdts has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm doing some simple subtraction: $difference = ($payment_total - $order_total); When I print out each of the above values, the $order_totals and $payment_totals always look normal, but sometimes the $difference gives me something like: 5.6843418860808e-14. Any ideas on what might be causing this? Thanks, JD

Replies are listed 'Best First'.
Re: numeric values acting funny
by tachyon (Chancellor) on Dec 11, 2004 at 01:59 UTC
Re: numeric values acting funny
by Errto (Vicar) on Dec 11, 2004 at 02:02 UTC
    This is discussed in more detail in Bug? 1+1 != 2. See in particular the replies from BrowserUk. The short answer is that this is just a consequence of using floating point arithmetic, and there are a number of ways around it depending on what you want to do.
Re: numeric values acting funny
by simonm (Vicar) on Dec 11, 2004 at 01:45 UTC
    This is scientific notation sometimes used for very large or small numbers; in this case, it's a very, very small number.

    This may be a side-effect of floating point math; consider using sprintf or other formatting tools to force this number to appear the way you expect.

Re: numeric values acting funny
by VSarkiss (Monsignor) on Dec 11, 2004 at 02:03 UTC

    Your problem isn't in Perl, but in how numbers are represented.

    There's an old rule in numerical analysis:

    Never subtract very close values from each other
    The problem, in very basic terms, is that your variables are the value you want, plus or minus some small "epsilon". If you subtract two very close values, all you end up with is ε1 ± ε2; in other words, garbage.

    Your best bet is to restructure the formulas so the subtraction isn't necessary.

      Your best bet is to restructure the formulas so the subtraction isn't necessary.

      This is I believe impossible given that the task rotates around money and spending some quantum of the available. Using integer math is probably a more practical solution. Math::Currency provides a nice transparent implementation that simulates dollars and cents, pounds and pence.....

      cheers

      tachyon

Re: numeric values acting funny
by TedPride (Priest) on Dec 12, 2004 at 22:04 UTC
    Just do everything in cents. The following or some variation should work fine:
    use strict; use warnings; my $payment_total = 415; my $order_total = 420; my $difference = $order_total - $payment_total; print cash($difference); sub cash { $_[0] = int($_[0] + .5); $_[0] /= 100 if $_[0] != 0; return sprintf('$%.2f', $_[0]) }