in reply to Re^12: Decimal Floating Point (DFP) and does Perl needs DFP?
in thread Decimal Floating Point (DFP) and does Perl needs DFP?

Consider yourself asked :)

Heh ... you might be expecting something more erudite than what I can deliver :-)
I was getting bogged down in examining different approaches that were giving different results, and scratching my head over what was the right thing to do. And then it occurred to me that all I had to do was resort to some pretty basic clear thinking.
So there's nothing too profound here, and I'm really just admitting to a haziness that was probably afflicting no-one but myself.
Sticking to base 2 arithmetic for the moment, for a double precision value such as
5.34 or, in binary:
1.0101010111000010100011110101110000101000111101011100e2
raised to the integer power of (say) 100, there can be only one correct result - namely the result you get when you multiply the original value by itself 99 times, such that no rounding is performed (ie to 5300-bit precision), and then round that 5300-bit result back to 53 bits.
If you allow other results, then you admit to there being more than one correct answer - which would be to ask more of arithmetic than it is generally prepared to give.
The good "pow" algorithms won't follow that exact procedure of course, but that final 53-bit value is the value that they ought to return - and the value that does get returned by both perl (mostly) and mpfr for the various cases I've tested.
So ... for 5.34 ** 100, the result (as calculated by both mpfr_pow and the multiplication chain) came out at
1.1001101101000111011101111001101101001011101110000100e241 which equates to the 15 digit value of
5.67708900158395e72

And my perl-5.20.0 (NV is double), perl came up with the the identical value for 5.34 ** 100.
(However, in 35 of the 3000 test cases I ran, perl was out by 1 ULP - but that's not bad for perl.)

For decimal arithmetic, it's essentially the same scenario - the value returned for 1.00001 ** 6e7 should be the same as yielded by multiplying the decimal 1.000001 by itself 59999999 times (without any rounding being done) and then rounding it down to the appropriate precision.
Luckily, in practice you can usually do *some* rounding without jeopardising the accuracy of the final rounded-down result, and I'm sure that the good "pow" algorithms make full use of that potential - as did LanX's Math::BigFloat approach.

Cheers,
Rob
  • Comment on Re^13: Decimal Floating Point (DFP) and does Perl needs DFP?

Replies are listed 'Best First'.
Re^14: Decimal Floating Point (DFP) and does Perl needs DFP?
by BrowserUk (Patriarch) on Jan 22, 2015 at 13:32 UTC
    Luckily, in practice you can usually do *some* rounding without jeopardising the accuracy of the final rounded-down result,

    That is the reason for Intel FPUs use of 80-bit extended doubles. The theory being that if the FPU does all its internal calculations with 64 bits of precision, then by the time the results are returned as a double (with its 53 bits of precision) any inaccuracies accumulated through intermediate calculations will be thrown away.

    Of course that's only true if the compiler(or programmer) correctly orders the calculations so that intermediate results can always be held in FP registers. Often the problem is that intemediate results get written out to ram (as doubles) to free up FP registers and thus the accumulated errors increase beyond their theoretic bounds.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
    In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked