in reply to Re: \$var == 1 fails when \$var = 1
in thread \$var == 1 fails when \$var = 1

Why does the order of addition matter?
```DB<8> printf '%.20f', 0.688
0.68799999999999994493
DB<9> printf '%.20f', 0.688 + 0.023
0.71099999999999996536
DB<10> printf '%.20f', 0.688 + 0.023  + 0.289
1.00000000000000000000
DB<11> printf '%.20f', 0.688 + 0.289 + 0.023
0.99999999999999988898
```
PS and thanks for the prompt answer!

Replies are listed 'Best First'.
Re^3: \$var == 1 fails when \$var = 1
by LanX (Archbishop) on Sep 20, 2018 at 15:33 UTC
Because you are accumulating different rounding errors and (most likely) a shifting mantissa changes the last bit to be rounded.

##### update

Rounding is often not very intuitive, try to avoid if possible.

If you want to track the details you need to look into the binary representation and the underlying C lib.

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

That sort of makes sense :-) Is there a module that covers over these sort of cracks? It would seem to be a routine problem.
Is there a module that covers over these sort of cracks?

The crack that has perl's print() function often lie to us about a floating point value is rather annoying.
You just need to remember that the floating point value that print() provides will be the same as that provided by printf "%.14e", whereas, if you want a practically useful value, you need to printf "%.16e".
Outputting more than 17 decimal digits of a double is generally of no use. If you want to see the exact value, use printf "%a" (which will display that exact value in hex).

I gather that there was once a \$# special variable (see perldoc perlvar) which allowed one to specify the decimal precision that print() would use.
But it has been abandoned and disabled owing to difficulties in its implementation.
You can, of course, write your own subroutine for printing floats in the format of your choice:
```sub p17 {
printf "%.16e\n", \$_;
}

sub ph {
printf "%a\n", \$_;
}