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

Can anyone tell me why:

perl -e 'print -8 + -15 * 0.5, "\n";' -15.5

does the right thing, and multiplies -15 times 0.5, then adds it (-7.5) to -8 to get -15.5, but:

print "LEQ/REQ: $leftEq[$_[0]][$i] $rightEq[$_[0]][$i]\n"; ($leftEq[$_[0]][$i], $rightEq[$_[0]][$i]) = ($leftEq[$_[0]][$i] + $leftStorDelta[$i] * $factor, $rightEq[$_[0]][$i] + $rightStorDelta[$i] * $factor); print "Fct: $factor Delt: $leftStorDelta[$i] $rightStorDelta[$i]\n"; print "Post-LEQ/REQ: $leftEq[$_[0]][$i] $rightEq[$_[0]][$i]\n\n";

gives output like this:

LEQ/REQ: -8 -8 Fct: 0.50 Delt: -15 -15 Post-LEQ/REQ: -8 -8

even though it should be the same darn thing. From what I can gather, it's treating $factor (0.5) like an integer, multiplying -8 by 1.

...but why?

It should be noted that I only need two decimal places of precision in the answer, so if there's a way I can avoid the whole floating point jungle and just deal with decimal numbers of a form \d.\d\d, that would be more than fine.

My main question is why I'm not getting any decimal precision at all when I multiply times $factor, yet it works just fine with constants in a 'perl -e' one-liner.

Replies are listed 'Best First'.
Re: Floating point hell
by GrandFather (Saint) on Dec 19, 2015 at 19:58 UTC

    Turning your code into something I can run gives:

    use strict; use warnings; my $leftEq = -8; my $rightEq = -8; my $factor = 0.5; my $leftStorDelta = -15; my $rightStorDelta = -15; print "LEQ/REQ: $leftEq $rightEq\n"; ($leftEq, $rightEq) = ($leftEq + $leftStorDelta * $factor, $rightEq + $rightStorDelta * +$factor); print "Fct: $factor Delt: $leftStorDelta $rightStorDelta\n"; print "Post-LEQ/REQ: $leftEq $rightEq\n\n"; printf "%0.2f, %0.2f\n", 1.23, 1.345;

    Prints:

    LEQ/REQ: -8 -8 Fct: 0.5 Delt: -15 -15 Post-LEQ/REQ: -15.5 -15.5 1.23, 1.35

    with a bonus line that shows printf in use.

    Premature optimization is the root of all job security
Re: Floating point hell
by AnomalousMonk (Archbishop) on Dec 19, 2015 at 22:43 UTC

    Just to pound this completely into the ground:

    c:\@Work\Perl>perl -wMstrict -le "my @leftEq = ([-8]); my @rightEq = ([-8]); ;; my @leftStorDelta = (-15); my @rightStorDelta = (-15); ;; $_[0] = 0; my $i = 0; my $factor = 0.5; ;; print \"LEQ/REQ: $leftEq[$_[0]][$i] $rightEq[$_[0]][$i]\n\"; ($leftEq[$_[0]][$i], $rightEq[$_[0]][$i]) = ($leftEq[$_[0]][$i] + $leftStorDelta[$i] * $factor, $rightEq[$_[0]][$i] + $rightStorDelta[$i] * $factor); print \"Fct: $factor Delt: $leftStorDelta[$i] $rightStorDelta[$i]\n\" +; print \"Post-LEQ/REQ: $leftEq[$_[0]][$i] $rightEq[$_[0]][$i]\n\n\"; " LEQ/REQ: -8 -8 Fct: 0.5 Delt: -15 -15 Post-LEQ/REQ: -15.5 -15.5
    And further to AnonyMonk's point above, I get your undesired  -8 -8 results if I just  use integer; before the computation.


    Give a man a fish:  <%-{-{-{-<

Re: Floating point hell
by Apero (Scribe) on Dec 19, 2015 at 19:55 UTC

    Try to provide a more realistic, and complete example of your problem, keeping the code to a minimum to reproduce the behavior you're seeing. Your current example does not output anything useful for me, only the output headers (no actual values, besides "Post" values of 0 0.) This makes your problem impossible to diagnose without more relevant information.

    Further, the example provided should almost always enable the use strict and use warnings pragmas. I get no fewer than 27 compilation errors using strict in your example; you should review these and in most cases correct them before requesting help as the compiler catches many possible mistakes for you.

    Multiplying and adding works as described in perlop for me. Given how you reference variables you never describe in the example, it's almost surely caused by code not shown.

    use strict; use warnings; my $factor = 0.5; my $base = -15; my $base2 = -8; result( "$base * $factor", $base * $factor ); result( "$base2 + $base * $factor", $base2 + $base * $factor ); # Show a result. # Pass it 2 args: # ARG1: display string to inform user about the calculation. # ARG2: displayed as a float, 2 place precision. sub result { printf "%s is: %.2f\n", shift // '', shift // 0; }

Re: Floating point hell
by Anonymous Monk on Dec 19, 2015 at 19:38 UTC
    ...but why?
    Probably because of something that isn't in your post. See sscce.org for details.

    Here's one example:

    $ perl -e 'use integer; print -8 + -15 * 0.5, "\n";'
    But I don't really want to guess.