in reply to Re: 4253.95 + 0.9 = 4254.84999999999 (need help to interpret internals)
in thread 4253.95 + 0.9 = 4254.84999999999 (need help to interpret internals)

Well, it may not be a problem with Perl, but it's a problem for me.

So can I avoid it somehow? Stringification of the values before doing the operation solves my problem. Why is that? Is it something accumulated that gets re-set?

(I understand that it changes Perl's internal representation of what is stored in the variable, but what I wonder is how and why that changes what it does when performing the addition).

This is something that popped up in an old application where I do basically the same thing all over the place, but this particular thing haven't been a problem in the past.

Right now I have "solved" id by stringifying the value before doing the calculation, but that doesn't feel very solid.

/J

  • Comment on Re^2: 4253.95 + 0.9 = 4254.84999999999 (need help to interpret internals)

Replies are listed 'Best First'.
Re^3: 4253.95 + 0.9 = 4254.84999999999 (need help to interpret internals)
by dragonchild (Archbishop) on Feb 25, 2005 at 14:24 UTC
    An alternative which is used in C a lot is to make them into integers by multiplying everything by 10**N where N is the number of decimal places (or precision) you want to have in your answer. Then, when you're done, you divide the answer by 10**N and you're good.

    *ponders* This sounds like a good candidate for a CPAN module doing overloaded math ... Or, you could just use Math::BigFloat (which may be overkill)

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re^3: 4253.95 + 0.9 = 4254.84999999999 (need help to interpret internals)
by Roy Johnson (Monsignor) on Feb 25, 2005 at 14:11 UTC
    When you stringify them, you're forcing perl to round them. If it makes you feel any better about it, you could explicitly round them with sprintf.

    Caution: Contents may have been coded under pressure.
Re^3: 4253.95 + 0.9 = 4254.84999999999 (need help to interpret internals)
by ikegami (Patriarch) on Feb 25, 2005 at 16:22 UTC
    So can I avoid it somehow?

    Yes, multiply everything by 100 (i.e. deal with cents instead of dollars), and divide by 100 (i.e. convert to dollars) when you print. You won't have the problem, because it doesn't occur for numbers with no decimals, unless they get really big (> 2 billion on a 32 bit system).

    >perl -e "$a=0; $a += 0.10 for (1..60); print($a, $/);" 5.99999999999999 >perl -e "$a=0; $a += 10 for (1..60); print($a/100, $/);" 6