in reply to Re^4: number comparison with a twist
in thread number comparison with a twist

I understand that the internal representation is (probably) floating point. However that is still an assumption of what the internal representation "decimal string" actually is. My point is that using the eq operator targets "decimal string" which has a lower precision (for DWIM reasons?), so you are absolutely right that that method smoothes the rounding errors from floats away

printf "%.20f",$var

This targeted floating point with high precision.

This is what I (presumably) hope to target with the eq:

printf "%.11f", $num2*100 ; # 1990.00000000000

I'm not sure if $.11f now shows the exact correct number of decimals (which should be 15 I believe), but as far as I can see this solves OP's problem and that is why I suggested it. Just using eq is in my opinion fine for this particular use case. For the rest floating point is always a pain in the... well, you know

Replies are listed 'Best First'.
Re^6: number comparison with a twist
by LanX (Saint) on Mar 02, 2020 at 18:22 UTC
    > My point is that using the eq operator targets "decimal string"

    Please see Re^3: number comparison with a twist and connected posts to why using == is far better here

    Using the small epsilon rounding of stringification is actually a good idea (and not much different to the diff solutions proposed by others) ...

    ... but one has to first prove that it always works for cents ( which I did)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      So I stole your test here for a moment...

      say join "\n", grep { sprintf ("%03d",$_) + 0 ne ($_/1000)*1000 } 0..9 +9999

      I needed to add a + 0 to be able to handle the trailing zero's. The funny thing is that in your case you would need to do the opposite ( "" . value) in case the value undergoes an arithmetic operation.

        This boils down to two alternatives to compare two numeric scalars with a minimal* rounding tolerance

        DB<65> $num1 = '0019.90'; $num2 = '019.9' DB<66> p $num1+0 eq $num2+0 1 DB<67> p "$num1" == "$num2" 1 DB<68>

        Not sure which one is technically better.

        I find the second one more readable and easier to explain.

        edit

        Well there are edge cases when the scalar is not purely numeric... but that's too complicated.

        update

        FWIW: the eq form can be further simplified with a unary +:

        DB<109> printf "%.20f\n",$_ for $a,$b 2547200.00000000000000000000 2547199.99999999950000000000 DB<110> p +$a eq +$b # unary + 1 + DB<111> p $a == $b # doesn't work DB<112> p "$a" == "$b" # preferred variant 1

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

        *) should be noted that this can't help fixing accumulated rounding errors.