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

perl -le 'print 5056.45 + 10112.92 == 15169.37 ? "as expected" : "perl + math sucks!"'

Replies are listed 'Best First'.
Re: Why does perl math suck?
by ikegami (Pope) on Jan 12, 2011 at 00:27 UTC
    $ cat a.c #include <stdio.h> int main() { printf("%s\n", 5056.45 + 10112.92 == 15169.37 ? "granted" : "Stop b +laming Perl for your own mistakes!"); return 0; } $ gcc -o a a.c && a Stop blaming Perl for your own mistakes!

    45/100, 92/100 and 37/100 are all periodic numbers in binary just like 1/3 is in decimal. It would take infinite storage to store it accurately as a floating point number (regardless of the language). As such, there are tiny differences between the number you specify any the number you actually have

    $ perl -e'printf "%.20e\n", $_ for @ARGV' 0.45 0.92 0.37 4.50000000000000011102e-01 9.20000000000000039968e-01 3.69999999999999995559e-01

    That's why you must include a tolerance for error when dealing with floating points numbers.

    $ perl -le 'print abs(5056.45 + 10112.92 - 15169.37) < 0.0001 ? "as ex +pected" : "perl math sucks!"' as expected $ perl -le 'print sprintf("%.4f", 5056.45 + 10112.92) eq sprintf("%.4f +", 15169.37) ? "as expected" : "perl math sucks!"' as expected

    That's 9 digits of precision, and you can even go higher.

Re: Why does perl math suck?
by Anonyrnous Monk (Hermit) on Jan 12, 2011 at 00:22 UTC
Re: Why does Perl 6 math suck less?
by moritz (Cardinal) on Jan 12, 2011 at 05:45 UTC
      Just out of curiosity ..
      How does Perl 6 get around this?

        By defaulting to rational numbers that are stored as two integers internally. As explained in the link I provided.

        (Note that floating point numbers are still accessible with by using scientifc notation, eg 0.1e0)

Re: Why does perl math suck?
by ww (Archbishop) on Jan 12, 2011 at 00:35 UTC
Re: Why does perl math suck?
by ikegami (Pope) on Jan 12, 2011 at 00:40 UTC
    To answer the "why", floating point numbers offer a good compromise between speed and storage size vs accuracy. There are alternatives with different tradeoffs (e.g. Math::BigFloat, Perl 6).
Re: Why does perl math suck?
by FunkyMonk (Chancellor) on Jan 12, 2011 at 00:55 UTC
    Integers are always stored exactly (assuming they're not too big), so you could use something like:
    perl -le 'my $n = 505645 + 1011292; print $n == 1516937 ? $n / 100 . " + as expected" : "Gah. sharkey was right all along!"'
Re: Why does perl math suck?
by Anonymous Monk on Jan 12, 2011 at 00:37 UTC
Re: Why does perl math suck?
by MidLifeXis (Monsignor) on Jan 12, 2011 at 14:12 UTC

    An otherwise interesting question that comes up periodically, but -- for the logic behind the question: "Why are you still beating your wife?" Assumption is made that Perl (or any other language using floats) is doing the wrong thing instead of assuming that something is wrong, but you don't know what.

    Update: sundialsvc4 is correct that the original is presented as "Have you stopped beating your wife?", but there is a slightly different twist on that presented by the OP - a direct accusation that Perl is currently doing something wrong, not that in the past, Perl has done something wrong. Therefore my change on the original.


      IIRC, the fallacy was stated, “have you stopped beating your wife?”


      One thing that is taught very early on in engineering schools is exactly how many of those digits on your pocket calculator are actually “significant.”   I remember a friend of mine explaining why, on a particularly difficult exam, the challenge of one question was how to arrive at the answer using no more than three consecutive math operations.   (Within four operations, apparently, all of the significance of the answer would have been lost.)   I nodded politely, but blankly ... and thanked my lucky stars that I didn’t go to Georgia Tech.   ;-)

        The order in which the operations are done matter more than the number of operations. Using a/d + b/d + c/d instead of (a + b + c)/d can yield different results, and not because of the number of operations.
Re: Why does perl math suck?
by tilly (Archbishop) on Jan 29, 2011 at 15:39 UTC
    perl -le 'print 5056.45 + 10112.92 eq 15169.37 ? "as expected" : "perl math sucks!"'
    works as expected. The reason is that Perl uses more digits in floating point calculations than it stringifies, so stringification rounds off to the expected number. (I didn't invent this trick.)