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

Hi Monks, I am facing a difficulty in perl I have two numbers... 3.624920464501920123E+08 3.624920464504015567E+08 when i store these two numbers in some scalar then it truncates last two three digits. i want to take the difference of these two numbers... but as the number stored is truncated the difference i get is not accurate.. what do i do...? how to solve this problem..? Thanks for an early reply Bye
  • Comment on Not able to substract 2 big numbers with the right precision

Replies are listed 'Best First'.
Re: Not able to substract 2 big numbers with the right precision
by Corion (Patriarch) on Aug 23, 2007 at 08:54 UTC

    Can you show us your code? Most likely, you're running afoul of floating point precision errors, but that's hard to tell without seeing any of your code. Math::BigInt or Math::BigFloat might help, or maybe tye's Math::BigApprox. These all have different advantages and drawbacks, depending on your speed requirements and precision requirements. Note that it does not make sense to have a (much) higher precision in your result than in your input data.

Re: Not able to substract 2 big numbers with the right precision
by RMGir (Prior) on Aug 23, 2007 at 11:40 UTC
    You really should consider reading What Every Computer Scientist Should Know About Floating-Point Arithmetic. It's a 44 page paper, but you really should know it.

    As the others have pointed out, there are arbitrary-precision libraries out there, but you're going to pay an efficiency price for using them. If you DO use them, make sure you check your results... In the case moritz demonstrated above, -Mbignum gives the correct answer, which you can check by reversing the operation:

    $ perl -Mbignum -e'print 3.624920464504015567E+08 + -0.0002095444,"\n" +' 362492046.4501920123 $ perl -Mbignum -e'print 3.624920464501920123E+08 + 0.0002095444,"\n" +' 362492046.4504015567

    Mike
Re: Not able to substract 2 big numbers with the right precision
by moritz (Cardinal) on Aug 23, 2007 at 08:56 UTC
    This is a problem of floating point numbers in general.

    You can try to circumvent it (with some performance penalty) by using bignum.

    $ perl -Mbignum -wle 'print 3.624920464501920123E+08 - 3.6249204645040 +15567E+08' -0.0002095444 $ perl -wle 'print 3.624920464501920123E+08 - 3.624920464504015567E+0 +8' -0.000209510326385498

    Actually I haven't checked which is more accurate, but you can give it a try.

Re: Not able to substract 2 big numbers with the right precision
by sgt (Deacon) on Aug 23, 2007 at 09:43 UTC

    besides bignum, you can also try some multiprecision package. This implies in general having a C library and a Perl module to interface with it. A example is Math::GMP or Math::Pari. Can be better to store everything first as strings and deal with separtely with exponents.

    if you want to try Math::Pari, on some systems there is a bug which prevents the build to fetch correctly the Pari lib. If you fetch it yourself and untar it in the module install dir everything should be fine

    cheers --stephan
Re: Not able to substract 2 big numbers with the right precision
by ikegami (Patriarch) on Aug 23, 2007 at 14:37 UTC

    Double precision floats (which is what 32-bit Perl uses for decimal numbers) have 53-bits of storage for the mantissa, so about 16 digits.

    Just like you can't store 257 in an 8-bit integer, you can't store 3.624920464501920123E+08 in a 53-bit floating point. I has nothing to do with floating point numbers really.

Re: Not able to substract 2 big numbers with the right precision
by ysth (Canon) on Aug 23, 2007 at 21:12 UTC
    Exactly what is producing those numbers? They look like they are the result of math using a 64-bit mantissa. On many platforms, perl can directly support that if built with -Duselongdouble or -Dusemorebits.