Bug#727841: powl() inaccurate but only at runtime
Package: libc6
Version: 2.13-38
Severity: normal
On amd64, powl() is generating inaccurate results when called at runtime,
but if a call to it gets constant-folded at compile time (by gcc 4.7)
then the constant-folded result is much more accurate.
$ cat t0.c
#include <math.h>
#include <stdio.h>
int main(void) {
int c = getchar();
printf("%.16La\n", powl((long double)c, -298.0L));
printf("%.16La\n", powl(10.0L, -298.0L));
return 0;
}
$ gcc t0.c -lm
$ echo | ./a.out
0x8.5f0468293f0ebc30p-993
0x8.5f0468293f0eb4e0p-993
The second of the two values emitted, the one resulting from constant
folding in gcc, is actually the closest long double value available
to the unrepresentable 10**-298. The first value emitted, resulting
from a runtime call to powl(), is far less accurate. The difference,
117 ulp, cannot be accounted for by the use of different rounding modes:
there must be actual different algorithms in use.
So (a) libc's powl() is inaccurate; and (b) gcc's constant folding on
powl() doesn't accurately simulate its runtime behaviour. I think these
are both bugs, but fixing the first will presumably fix the second too,
so for now I'm only reporting this against libc.
Relevant package versions:
libc6:amd64 2.13-38
libc6-dbg:amd64 2.13-38
libc6-dev:amd64 2.13-38
libc6-dev-i386 2.13-38
libc6-i386 2.13-38
libc6-pic:amd64 2.13-38
gcc 4:4.7.2-1
gcc-4.7 4.7.2-5
gcc-4.7-base:amd64 4.7.2-5
gcc-4.7-doc 4.7.2-2
gcc-4.7-locales 4.7.2-5
gcc-4.7-multilib 4.7.2-5
gcc-multilib 4:4.7.2-1
-zefram
Reply to: