The IBM long double implementation of erfl() and erfcl() both give inaccurate results when given a negative argument such that the component doubles have differing sign. Also, erfl() with a large negative argument returns +1.0 rather than -1.0. The following compiled with -O0 shows one such bad result. (Compare with results from -O2 where gcc evalates erfl and erfl.) #include <stdio.h> #include <math.h> int main (void) { long double x, z; union { long double ld; double d[2]; } u; x = -0x1.fffffffffffff8p-2L; z = erfl (x); u.ld = x; printf ("%24.21Lf %36La %21a %21a\n", u.ld, u.ld, u.d[0], u.d[1]); u.ld = z; printf ("%24.21Lf %36La %21a %21a\n", u.ld, u.ld, u.d[0], u.d[1]); z = erfcl (x); u.ld = z; printf ("%24.21Lf %36La %21a %21a\n", u.ld, u.ld, u.d[0], u.d[1]); return 0; }
Fixed