The powl implementations for x86 and x86_64 work essentially through exp2 (y * log2 (x)). This does not produce accurate results for large outputs; you need about 15 extra bits of precision in the evaluation of y * log2 (x) to do that. As an example, powl (1e4932L, 0.75L) is 4840ulp off from the expected 1e3699L on x86_64.
For integer exponents a different algorithm is used; it's still not very accurate, e.g. 45ulp error for powl (10, 4932); that has the same underlying cause as the inaccuracy described for pow in bug 706.
Created attachment 6328 [details]
Find attached a test case. The approximations to 1e4932L and 1e3699L
are computed through an (exact) ldexpl call, from a mantissa that was
computed with GNU clisp's high-precision long-float numbers.
$ gcc -Wall foo.c -lm
Expected result (without any rounding errors):
x = 1e+4932
y = 0.75
x^y = 1e+3699
Actual result (on x86 and x86_64):
x = 1.000000000000000000006018949387963891324e+4932
y = 0.75
x^y = 1.000000000000000298896762326719536039811e+3699
As you can see:
1) x^y has only 15 valid digits after the decimal point.
2) The printf of x has 22 correct digits after the decimal point; this matches
the 64 mantissa bits in an x86 'long double'.
Fixed for 2.17 by:
Author: Joseph Myers <firstname.lastname@example.org>
Date: Wed Nov 28 13:40:54 2012 +0000
Fix powl inaccuracy for x86_64 and x86 (bug 13881).
Created attachment 11802 [details]
Test case for powl accuracy
powl is still less accurate than pow in version 2.27 (both gcc and clang).
The attached test case powl.cpp has powl 5 times more inaccurate than pow. I have seen worse cases, but I have chosen a test case where it is easy to calculate the correct value. I have not seen any case where powl is more accurate than pow.
Some more test cases:
powl(9.4401197044207130E-01,9.0396338480980503E+03) relative error 7.9E-13
powl(9.6205229632635447E-01,9.0396338480980503E+03) relative error 5.1E-13
powl(1.0567906354279399E+00,9.0396338480980503E+03) relative error 5.7E-13
powl(9.5952957579581444E-01,-1.6994966845030955E+04) relative error 1.8E-12
powl(9.4249308583367331E-01,5.1811882606772378E+03) relative error 6.4E-13
powl(1.0537202715568794E+00,5.1811882606772378E+03) relative error 4.2E-13
(In reply to email@example.com from comment #5)
> Please reopen.
> powl is still less accurate than pow in version 2.27 (both gcc and clang).
> The attached test case powl.cpp has powl 5 times more inaccurate than pow. I
> have seen worse cases, but I have chosen a test case where it is easy to
> calculate the correct value. I have not seen any case where powl is more
> accurate than pow.
Would you please file a separate bug for that? Thanks.