Merge remote-tracking branch 'nsz/math'
authorRich Felker <dalias@aerifal.cx>
Thu, 15 Nov 2012 13:37:58 +0000 (08:37 -0500)
committerRich Felker <dalias@aerifal.cx>
Thu, 15 Nov 2012 13:37:58 +0000 (08:37 -0500)
87 files changed:
include/complex.h
src/complex/__cexp.c
src/complex/__cexpf.c
src/complex/cacos.c
src/complex/cacosf.c
src/complex/cacosh.c
src/complex/cacoshf.c
src/complex/cacoshl.c
src/complex/cacosl.c
src/complex/casin.c
src/complex/casinf.c
src/complex/casinh.c
src/complex/casinhf.c
src/complex/casinhl.c
src/complex/casinl.c
src/complex/catanh.c
src/complex/catanhf.c
src/complex/catanhl.c
src/complex/ccos.c
src/complex/ccosf.c
src/complex/ccosh.c
src/complex/ccoshf.c
src/complex/ccosl.c
src/complex/cexp.c
src/complex/cexpf.c
src/complex/clog.c
src/complex/clogf.c
src/complex/clogl.c
src/complex/conj.c
src/complex/conjf.c
src/complex/conjl.c
src/complex/cproj.c
src/complex/cprojf.c
src/complex/cprojl.c
src/complex/csin.c
src/complex/csinf.c
src/complex/csinh.c
src/complex/csinhf.c
src/complex/csinl.c
src/complex/csqrt.c
src/complex/csqrtf.c
src/complex/ctan.c
src/complex/ctanf.c
src/complex/ctanh.c
src/complex/ctanhf.c
src/complex/ctanl.c
src/fenv/fenv.c
src/fenv/feupdateenv.c
src/internal/libm.h
src/math/__invtrigl.c
src/math/__invtrigl.h
src/math/acos.c
src/math/acosl.c
src/math/asinl.c
src/math/atan2.c
src/math/atan2l.c
src/math/atanl.c
src/math/exp10l.c
src/math/expm1l.c
src/math/fma.c
src/math/fmaf.c
src/math/fmal.c
src/math/hypot.c
src/math/hypotf.c
src/math/ilogb.c
src/math/ilogbf.c
src/math/ilogbl.c
src/math/llrintl.c
src/math/log1pl.c
src/math/log2l.c
src/math/logb.c
src/math/logbf.c
src/math/logbl.c
src/math/logl.c
src/math/lrint.c
src/math/lrintl.c
src/math/modf.c
src/math/modff.c
src/math/nearbyint.c
src/math/nearbyintf.c
src/math/nearbyintl.c
src/math/nextafter.c
src/math/nextafterf.c
src/math/nexttoward.c
src/math/nexttowardf.c
src/math/scalbn.c
src/math/scalbnf.c

index b4bcb22..8206e02 100644 (file)
@@ -112,6 +112,15 @@ long double creall(long double complex);
 #define cimagf(x) __CIMAG(x, float)
 #define cimagl(x) __CIMAG(x, long double)
 
+#define __CMPLX(x, y, t) \
+       ((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z)
+
+#if __STDC_VERSION__ >= 201112L
+#define CMPLX(x, y) __CMPLX(x, y, double)
+#define CMPLXF(x, y) __CMPLX(x, y, float)
+#define CMPLXL(x, y) __CMPLX(x, y, long double)
+#endif
+
 #ifdef __cplusplus
 }
 #endif
index f603e2b..05ac28c 100644 (file)
@@ -83,5 +83,5 @@ double complex __ldexp_cexp(double complex z, int expt)
        half_expt = expt - half_expt;
        INSERT_WORDS(scale2, (0x3ff + half_expt) << 20, 0);
 
-       return cpack(cos(y) * exp_x * scale1 * scale2, sin(y) * exp_x * scale1 * scale2);
+       return CMPLX(cos(y) * exp_x * scale1 * scale2, sin(y) * exp_x * scale1 * scale2);
 }
index 47168e8..69b5404 100644 (file)
@@ -63,6 +63,6 @@ float complex __ldexp_cexpf(float complex z, int expt)
        half_expt = expt - half_expt;
        SET_FLOAT_WORD(scale2, (0x7f + half_expt) << 23);
 
-       return cpackf(cosf(y) * exp_x * scale1 * scale2,
+       return CMPLXF(cosf(y) * exp_x * scale1 * scale2,
          sinf(y) * exp_x * scale1 * scale2);
 }
index 3aca051..27c3563 100644 (file)
@@ -7,5 +7,5 @@
 double complex cacos(double complex z)
 {
        z = casin(z);
-       return cpack(M_PI_2 - creal(z), -cimag(z));
+       return CMPLX(M_PI_2 - creal(z), -cimag(z));
 }
index 563766e..1185265 100644 (file)
@@ -5,5 +5,5 @@
 float complex cacosf(float complex z)
 {
        z = casinf(z);
-       return cpackf((float)M_PI_2 - crealf(z), -cimagf(z));
+       return CMPLXF((float)M_PI_2 - crealf(z), -cimagf(z));
 }
index c2dfc1b..8c68cb0 100644 (file)
@@ -5,5 +5,5 @@
 double complex cacosh(double complex z)
 {
        z = cacos(z);
-       return cpack(-cimag(z), creal(z));
+       return CMPLX(-cimag(z), creal(z));
 }
index 37ff880..ade01c0 100644 (file)
@@ -3,5 +3,5 @@
 float complex cacoshf(float complex z)
 {
        z = cacosf(z);
-       return cpackf(-cimagf(z), crealf(z));
+       return CMPLXF(-cimagf(z), crealf(z));
 }
index 2a04e27..6534255 100644 (file)
@@ -9,6 +9,6 @@ long double complex cacoshl(long double complex z)
 long double complex cacoshl(long double complex z)
 {
        z = cacosl(z);
-       return cpackl(-cimagl(z), creall(z));
+       return CMPLXL(-cimagl(z), creall(z));
 }
 #endif
index 5992e05..7fd4a2f 100644 (file)
@@ -11,6 +11,6 @@ long double complex cacosl(long double complex z)
 long double complex cacosl(long double complex z)
 {
        z = casinl(z);
-       return cpackl(PI_2 - creall(z), -cimagl(z));
+       return CMPLXL(PI_2 - creall(z), -cimagl(z));
 }
 #endif
index 79aff27..dfdda98 100644 (file)
@@ -11,6 +11,6 @@ double complex casin(double complex z)
 
        x = creal(z);
        y = cimag(z);
-       w = cpack(1.0 - (x - y)*(x + y), -2.0*x*y);
-       return clog(cpack(-y, x) + csqrt(w));
+       w = CMPLX(1.0 - (x - y)*(x + y), -2.0*x*y);
+       return clog(CMPLX(-y, x) + csqrt(w));
 }
index cb9863f..93f0e33 100644 (file)
@@ -9,6 +9,6 @@ float complex casinf(float complex z)
 
        x = crealf(z);
        y = cimagf(z);
-       w = cpackf(1.0 - (x - y)*(x + y), -2.0*x*y);
-       return clogf(cpackf(-y, x) + csqrtf(w));
+       w = CMPLXF(1.0 - (x - y)*(x + y), -2.0*x*y);
+       return clogf(CMPLXF(-y, x) + csqrtf(w));
 }
index f2b3fef..b57fe8c 100644 (file)
@@ -4,6 +4,6 @@
 
 double complex casinh(double complex z)
 {
-       z = casin(cpack(-cimag(z), creal(z)));
-       return cpack(cimag(z), -creal(z));
+       z = casin(CMPLX(-cimag(z), creal(z)));
+       return CMPLX(cimag(z), -creal(z));
 }
index ed4af64..a11bf90 100644 (file)
@@ -2,6 +2,6 @@
 
 float complex casinhf(float complex z)
 {
-       z = casinf(cpackf(-cimagf(z), crealf(z)));
-       return cpackf(cimagf(z), -crealf(z));
+       z = casinf(CMPLXF(-cimagf(z), crealf(z)));
+       return CMPLXF(cimagf(z), -crealf(z));
 }
index e5d80ce..714f189 100644 (file)
@@ -8,7 +8,7 @@ long double complex casinhl(long double complex z)
 #else
 long double complex casinhl(long double complex z)
 {
-       z = casinl(cpackl(-cimagl(z), creall(z)));
-       return cpackl(cimagl(z), -creall(z));
+       z = casinl(CMPLXL(-cimagl(z), creall(z)));
+       return CMPLXL(cimagl(z), -creall(z));
 }
 #endif
index f9aa8de..0916c60 100644 (file)
@@ -14,7 +14,7 @@ long double complex casinl(long double complex z)
 
        x = creall(z);
        y = cimagl(z);
-       w = cpackl(1.0 - (x - y)*(x + y), -2.0*x*y);
-       return clogl(cpackl(-y, x) + csqrtl(w));
+       w = CMPLXL(1.0 - (x - y)*(x + y), -2.0*x*y);
+       return clogl(CMPLXL(-y, x) + csqrtl(w));
 }
 #endif
index b162802..e248d9b 100644 (file)
@@ -4,6 +4,6 @@
 
 double complex catanh(double complex z)
 {
-       z = catan(cpack(-cimag(z), creal(z)));
-       return cpack(cimag(z), -creal(z));
+       z = catan(CMPLX(-cimag(z), creal(z)));
+       return CMPLX(cimag(z), -creal(z));
 }
index e1d1e64..4a5eb04 100644 (file)
@@ -2,6 +2,6 @@
 
 float complex catanhf(float complex z)
 {
-       z = catanf(cpackf(-cimagf(z), crealf(z)));
-       return cpackf(cimagf(z), -crealf(z));
+       z = catanf(CMPLXF(-cimagf(z), crealf(z)));
+       return CMPLXF(cimagf(z), -crealf(z));
 }
index 0a9374a..a5dd538 100644 (file)
@@ -8,7 +8,7 @@ long double complex catanhl(long double complex z)
 #else
 long double complex catanhl(long double complex z)
 {
-       z = catanl(cpackl(-cimagl(z), creall(z)));
-       return cpackl(cimagl(z), -creall(z));
+       z = catanl(CMPLXL(-cimagl(z), creall(z)));
+       return CMPLXL(cimagl(z), -creall(z));
 }
 #endif
index 5754c23..645aec2 100644 (file)
@@ -4,5 +4,5 @@
 
 double complex ccos(double complex z)
 {
-       return ccosh(cpack(-cimag(z), creal(z)));
+       return ccosh(CMPLX(-cimag(z), creal(z)));
 }
index 9b72c4f..9a67241 100644 (file)
@@ -2,5 +2,5 @@
 
 float complex ccosf(float complex z)
 {
-       return ccoshf(cpackf(-cimagf(z), crealf(z)));
+       return ccoshf(CMPLXF(-cimagf(z), crealf(z)));
 }
index 81f2943..401f3c6 100644 (file)
@@ -55,23 +55,23 @@ double complex ccosh(double complex z)
        /* Handle the nearly-non-exceptional cases where x and y are finite. */
        if (ix < 0x7ff00000 && iy < 0x7ff00000) {
                if ((iy | ly) == 0)
-                       return cpack(cosh(x), x * y);
+                       return CMPLX(cosh(x), x * y);
                if (ix < 0x40360000)    /* small x: normal case */
-                       return cpack(cosh(x) * cos(y), sinh(x) * sin(y));
+                       return CMPLX(cosh(x) * cos(y), sinh(x) * sin(y));
 
                /* |x| >= 22, so cosh(x) ~= exp(|x|) */
                if (ix < 0x40862e42) {
                        /* x < 710: exp(|x|) won't overflow */
                        h = exp(fabs(x)) * 0.5;
-                       return cpack(h * cos(y), copysign(h, x) * sin(y));
+                       return CMPLX(h * cos(y), copysign(h, x) * sin(y));
                } else if (ix < 0x4096bbaa) {
                        /* x < 1455: scale to avoid overflow */
-                       z = __ldexp_cexp(cpack(fabs(x), y), -1);
-                       return cpack(creal(z), cimag(z) * copysign(1, x));
+                       z = __ldexp_cexp(CMPLX(fabs(x), y), -1);
+                       return CMPLX(creal(z), cimag(z) * copysign(1, x));
                } else {
                        /* x >= 1455: the result always overflows */
                        h = huge * x;
-                       return cpack(h * h * cos(y), h * sin(y));
+                       return CMPLX(h * h * cos(y), h * sin(y));
                }
        }
 
@@ -85,7 +85,7 @@ double complex ccosh(double complex z)
         * the same as d(NaN).
         */
        if ((ix | lx) == 0 && iy >= 0x7ff00000)
-               return cpack(y - y, copysign(0, x * (y - y)));
+               return CMPLX(y - y, copysign(0, x * (y - y)));
 
        /*
         * cosh(+-Inf +- I 0) = +Inf + I (+-)(+-)0.
@@ -95,8 +95,8 @@ double complex ccosh(double complex z)
         */
        if ((iy | ly) == 0 && ix >= 0x7ff00000) {
                if (((hx & 0xfffff) | lx) == 0)
-                       return cpack(x * x, copysign(0, x) * y);
-               return cpack(x * x, copysign(0, (x + x) * y));
+                       return CMPLX(x * x, copysign(0, x) * y);
+               return CMPLX(x * x, copysign(0, (x + x) * y));
        }
 
        /*
@@ -108,7 +108,7 @@ double complex ccosh(double complex z)
         * nonzero x.  Choice = don't raise (except for signaling NaNs).
         */
        if (ix < 0x7ff00000 && iy >= 0x7ff00000)
-               return cpack(y - y, x * (y - y));
+               return CMPLX(y - y, x * (y - y));
 
        /*
         * cosh(+-Inf + I NaN)  = +Inf + I d(NaN).
@@ -121,8 +121,8 @@ double complex ccosh(double complex z)
         */
        if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) {
                if (iy >= 0x7ff00000)
-                       return cpack(x * x, x * (y - y));
-               return cpack((x * x) * cos(y), x * sin(y));
+                       return CMPLX(x * x, x * (y - y));
+               return CMPLX((x * x) * cos(y), x * sin(y));
        }
 
        /*
@@ -136,5 +136,5 @@ double complex ccosh(double complex z)
         * Optionally raises the invalid floating-point exception for finite
         * nonzero y.  Choice = don't raise (except for signaling NaNs).
         */
-       return cpack((x * x) * (y - y), (x + x) * (y - y));
+       return CMPLX((x * x) * (y - y), (x + x) * (y - y));
 }
index 683e77f..90acfe0 100644 (file)
@@ -48,43 +48,43 @@ float complex ccoshf(float complex z)
 
        if (ix < 0x7f800000 && iy < 0x7f800000) {
                if (iy == 0)
-                       return cpackf(coshf(x), x * y);
+                       return CMPLXF(coshf(x), x * y);
                if (ix < 0x41100000)    /* small x: normal case */
-                       return cpackf(coshf(x) * cosf(y), sinhf(x) * sinf(y));
+                       return CMPLXF(coshf(x) * cosf(y), sinhf(x) * sinf(y));
 
                /* |x| >= 9, so cosh(x) ~= exp(|x|) */
                if (ix < 0x42b17218) {
                        /* x < 88.7: expf(|x|) won't overflow */
                        h = expf(fabsf(x)) * 0.5f;
-                       return cpackf(h * cosf(y), copysignf(h, x) * sinf(y));
+                       return CMPLXF(h * cosf(y), copysignf(h, x) * sinf(y));
                } else if (ix < 0x4340b1e7) {
                        /* x < 192.7: scale to avoid overflow */
-                       z = __ldexp_cexpf(cpackf(fabsf(x), y), -1);
-                       return cpackf(crealf(z), cimagf(z) * copysignf(1, x));
+                       z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1);
+                       return CMPLXF(crealf(z), cimagf(z) * copysignf(1, x));
                } else {
                        /* x >= 192.7: the result always overflows */
                        h = huge * x;
-                       return cpackf(h * h * cosf(y), h * sinf(y));
+                       return CMPLXF(h * h * cosf(y), h * sinf(y));
                }
        }
 
        if (ix == 0 && iy >= 0x7f800000)
-               return cpackf(y - y, copysignf(0, x * (y - y)));
+               return CMPLXF(y - y, copysignf(0, x * (y - y)));
 
        if (iy == 0 && ix >= 0x7f800000) {
                if ((hx & 0x7fffff) == 0)
-                       return cpackf(x * x, copysignf(0, x) * y);
-               return cpackf(x * x, copysignf(0, (x + x) * y));
+                       return CMPLXF(x * x, copysignf(0, x) * y);
+               return CMPLXF(x * x, copysignf(0, (x + x) * y));
        }
 
        if (ix < 0x7f800000 && iy >= 0x7f800000)
-               return cpackf(y - y, x * (y - y));
+               return CMPLXF(y - y, x * (y - y));
 
        if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) {
                if (iy >= 0x7f800000)
-                       return cpackf(x * x, x * (y - y));
-               return cpackf((x * x) * cosf(y), x * sinf(y));
+                       return CMPLXF(x * x, x * (y - y));
+               return CMPLXF((x * x) * cosf(y), x * sinf(y));
        }
 
-       return cpackf((x * x) * (y - y), (x + x) * (y - y));
+       return CMPLXF((x * x) * (y - y), (x + x) * (y - y));
 }
index e37825a..d787047 100644 (file)
@@ -8,6 +8,6 @@ long double complex ccosl(long double complex z)
 #else
 long double complex ccosl(long double complex z)
 {
-       return ccoshl(cpackl(-cimagl(z), creall(z)));
+       return ccoshl(CMPLXL(-cimagl(z), creall(z)));
 }
 #endif
index 3b8bb75..5118e00 100644 (file)
@@ -44,22 +44,22 @@ double complex cexp(double complex z)
 
        /* cexp(x + I 0) = exp(x) + I 0 */
        if ((hy | ly) == 0)
-               return cpack(exp(x), y);
+               return CMPLX(exp(x), y);
        EXTRACT_WORDS(hx, lx, x);
        /* cexp(0 + I y) = cos(y) + I sin(y) */
        if (((hx & 0x7fffffff) | lx) == 0)
-               return cpack(cos(y), sin(y));
+               return CMPLX(cos(y), sin(y));
 
        if (hy >= 0x7ff00000) {
                if (lx != 0 || (hx & 0x7fffffff) != 0x7ff00000) {
                        /* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */
-                       return cpack(y - y, y - y);
+                       return CMPLX(y - y, y - y);
                } else if (hx & 0x80000000) {
                        /* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */
-                       return cpack(0.0, 0.0);
+                       return CMPLX(0.0, 0.0);
                } else {
                        /* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */
-                       return cpack(x, y - y);
+                       return CMPLX(x, y - y);
                }
        }
 
@@ -78,6 +78,6 @@ double complex cexp(double complex z)
                 *  -  x = NaN (spurious inexact exception from y)
                 */
                exp_x = exp(x);
-               return cpack(exp_x * cos(y), exp_x * sin(y));
+               return CMPLX(exp_x * cos(y), exp_x * sin(y));
        }
 }
index 0cf13a3..1a09964 100644 (file)
@@ -44,22 +44,22 @@ float complex cexpf(float complex z)
 
        /* cexp(x + I 0) = exp(x) + I 0 */
        if (hy == 0)
-               return cpackf(expf(x), y);
+               return CMPLXF(expf(x), y);
        GET_FLOAT_WORD(hx, x);
        /* cexp(0 + I y) = cos(y) + I sin(y) */
        if ((hx & 0x7fffffff) == 0)
-               return cpackf(cosf(y), sinf(y));
+               return CMPLXF(cosf(y), sinf(y));
 
        if (hy >= 0x7f800000) {
                if ((hx & 0x7fffffff) != 0x7f800000) {
                        /* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */
-                       return cpackf(y - y, y - y);
+                       return CMPLXF(y - y, y - y);
                } else if (hx & 0x80000000) {
                        /* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */
-                       return cpackf(0.0, 0.0);
+                       return CMPLXF(0.0, 0.0);
                } else {
                        /* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */
-                       return cpackf(x, y - y);
+                       return CMPLXF(x, y - y);
                }
        }
 
@@ -78,6 +78,6 @@ float complex cexpf(float complex z)
                 *  -  x = NaN (spurious inexact exception from y)
                 */
                exp_x = expf(x);
-               return cpackf(exp_x * cosf(y), exp_x * sinf(y));
+               return CMPLXF(exp_x * cosf(y), exp_x * sinf(y));
        }
 }
index 6f10a11..12aae9c 100644 (file)
@@ -10,5 +10,5 @@ double complex clog(double complex z)
 
        r = cabs(z);
        phi = carg(z);
-       return cpack(log(r), phi);
+       return CMPLX(log(r), phi);
 }
index f3aec54..e9b32e6 100644 (file)
@@ -8,5 +8,5 @@ float complex clogf(float complex z)
 
        r = cabsf(z);
        phi = cargf(z);
-       return cpackf(logf(r), phi);
+       return CMPLXF(logf(r), phi);
 }
index 5b84ba5..18f1608 100644 (file)
@@ -13,6 +13,6 @@ long double complex clogl(long double complex z)
 
        r = cabsl(z);
        phi = cargl(z);
-       return cpackl(logl(r), phi);
+       return CMPLXL(logl(r), phi);
 }
 #endif
index 4aceea7..0b3f5f4 100644 (file)
@@ -2,5 +2,5 @@
 
 double complex conj(double complex z)
 {
-       return cpack(creal(z), -cimag(z));
+       return CMPLX(creal(z), -cimag(z));
 }
index 3155680..9af6b2c 100644 (file)
@@ -2,5 +2,5 @@
 
 float complex conjf(float complex z)
 {
-       return cpackf(crealf(z), -cimagf(z));
+       return CMPLXF(crealf(z), -cimagf(z));
 }
index 0133226..67f11b9 100644 (file)
@@ -2,5 +2,5 @@
 
 long double complex conjl(long double complex z)
 {
-       return cpackl(creall(z), -cimagl(z));
+       return CMPLXL(creall(z), -cimagl(z));
 }
index 1cf9bb9..15f358a 100644 (file)
@@ -3,6 +3,6 @@
 double complex cproj(double complex z)
 {
        if (isinf(creal(z)) || isinf(cimag(z)))
-               return cpack(INFINITY, copysign(0.0, creal(z)));
+               return CMPLX(INFINITY, copysign(0.0, creal(z)));
        return z;
 }
index 7112974..653be5e 100644 (file)
@@ -3,6 +3,6 @@
 float complex cprojf(float complex z)
 {
        if (isinf(crealf(z)) || isinf(cimagf(z)))
-               return cpackf(INFINITY, copysignf(0.0, crealf(z)));
+               return CMPLXF(INFINITY, copysignf(0.0, crealf(z)));
        return z;
 }
index 72e50cf..6731aaa 100644 (file)
@@ -9,7 +9,7 @@ long double complex cprojl(long double complex z)
 long double complex cprojl(long double complex z)
 {
        if (isinf(creall(z)) || isinf(cimagl(z)))
-               return cpackl(INFINITY, copysignl(0.0, creall(z)));
+               return CMPLXL(INFINITY, copysignl(0.0, creall(z)));
        return z;
 }
 #endif
index 246a459..ad8ae67 100644 (file)
@@ -4,6 +4,6 @@
 
 double complex csin(double complex z)
 {
-       z = csinh(cpack(-cimag(z), creal(z)));
-       return cpack(cimag(z), -creal(z));
+       z = csinh(CMPLX(-cimag(z), creal(z)));
+       return CMPLX(cimag(z), -creal(z));
 }
index 3aabe8f..60b3cba 100644 (file)
@@ -2,6 +2,6 @@
 
 float complex csinf(float complex z)
 {
-       z = csinhf(cpackf(-cimagf(z), crealf(z)));
-       return cpackf(cimagf(z), -crealf(z));
+       z = csinhf(CMPLXF(-cimagf(z), crealf(z)));
+       return CMPLXF(cimagf(z), -crealf(z));
 }
index fe16f06..0f8035d 100644 (file)
@@ -55,23 +55,23 @@ double complex csinh(double complex z)
        /* Handle the nearly-non-exceptional cases where x and y are finite. */
        if (ix < 0x7ff00000 && iy < 0x7ff00000) {
                if ((iy | ly) == 0)
-                       return cpack(sinh(x), y);
+                       return CMPLX(sinh(x), y);
                if (ix < 0x40360000)    /* small x: normal case */
-                       return cpack(sinh(x) * cos(y), cosh(x) * sin(y));
+                       return CMPLX(sinh(x) * cos(y), cosh(x) * sin(y));
 
                /* |x| >= 22, so cosh(x) ~= exp(|x|) */
                if (ix < 0x40862e42) {
                        /* x < 710: exp(|x|) won't overflow */
                        h = exp(fabs(x)) * 0.5;
-                       return cpack(copysign(h, x) * cos(y), h * sin(y));
+                       return CMPLX(copysign(h, x) * cos(y), h * sin(y));
                } else if (ix < 0x4096bbaa) {
                        /* x < 1455: scale to avoid overflow */
-                       z = __ldexp_cexp(cpack(fabs(x), y), -1);
-                       return cpack(creal(z) * copysign(1, x), cimag(z));
+                       z = __ldexp_cexp(CMPLX(fabs(x), y), -1);
+                       return CMPLX(creal(z) * copysign(1, x), cimag(z));
                } else {
                        /* x >= 1455: the result always overflows */
                        h = huge * x;
-                       return cpack(h * cos(y), h * h * sin(y));
+                       return CMPLX(h * cos(y), h * h * sin(y));
                }
        }
 
@@ -85,7 +85,7 @@ double complex csinh(double complex z)
         * the same as d(NaN).
         */
        if ((ix | lx) == 0 && iy >= 0x7ff00000)
-               return cpack(copysign(0, x * (y - y)), y - y);
+               return CMPLX(copysign(0, x * (y - y)), y - y);
 
        /*
         * sinh(+-Inf +- I 0) = +-Inf + I +-0.
@@ -94,8 +94,8 @@ double complex csinh(double complex z)
         */
        if ((iy | ly) == 0 && ix >= 0x7ff00000) {
                if (((hx & 0xfffff) | lx) == 0)
-                       return cpack(x, y);
-               return cpack(x, copysign(0, y));
+                       return CMPLX(x, y);
+               return CMPLX(x, copysign(0, y));
        }
 
        /*
@@ -107,7 +107,7 @@ double complex csinh(double complex z)
         * nonzero x.  Choice = don't raise (except for signaling NaNs).
         */
        if (ix < 0x7ff00000 && iy >= 0x7ff00000)
-               return cpack(y - y, x * (y - y));
+               return CMPLX(y - y, x * (y - y));
 
        /*
         * sinh(+-Inf + I NaN)  = +-Inf + I d(NaN).
@@ -122,8 +122,8 @@ double complex csinh(double complex z)
         */
        if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) {
                if (iy >= 0x7ff00000)
-                       return cpack(x * x, x * (y - y));
-               return cpack(x * cos(y), INFINITY * sin(y));
+                       return CMPLX(x * x, x * (y - y));
+               return CMPLX(x * cos(y), INFINITY * sin(y));
        }
 
        /*
@@ -137,5 +137,5 @@ double complex csinh(double complex z)
         * Optionally raises the invalid floating-point exception for finite
         * nonzero y.  Choice = don't raise (except for signaling NaNs).
         */
-       return cpack((x * x) * (y - y), (x + x) * (y - y));
+       return CMPLX((x * x) * (y - y), (x + x) * (y - y));
 }
index bbb116c..49697f0 100644 (file)
@@ -48,43 +48,43 @@ float complex csinhf(float complex z)
 
        if (ix < 0x7f800000 && iy < 0x7f800000) {
                if (iy == 0)
-                       return cpackf(sinhf(x), y);
+                       return CMPLXF(sinhf(x), y);
                if (ix < 0x41100000)    /* small x: normal case */
-                       return cpackf(sinhf(x) * cosf(y), coshf(x) * sinf(y));
+                       return CMPLXF(sinhf(x) * cosf(y), coshf(x) * sinf(y));
 
                /* |x| >= 9, so cosh(x) ~= exp(|x|) */
                if (ix < 0x42b17218) {
                        /* x < 88.7: expf(|x|) won't overflow */
                        h = expf(fabsf(x)) * 0.5f;
-                       return cpackf(copysignf(h, x) * cosf(y), h * sinf(y));
+                       return CMPLXF(copysignf(h, x) * cosf(y), h * sinf(y));
                } else if (ix < 0x4340b1e7) {
                        /* x < 192.7: scale to avoid overflow */
-                       z = __ldexp_cexpf(cpackf(fabsf(x), y), -1);
-                       return cpackf(crealf(z) * copysignf(1, x), cimagf(z));
+                       z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1);
+                       return CMPLXF(crealf(z) * copysignf(1, x), cimagf(z));
                } else {
                        /* x >= 192.7: the result always overflows */
                        h = huge * x;
-                       return cpackf(h * cosf(y), h * h * sinf(y));
+                       return CMPLXF(h * cosf(y), h * h * sinf(y));
                }
        }
 
        if (ix == 0 && iy >= 0x7f800000)
-               return cpackf(copysignf(0, x * (y - y)), y - y);
+               return CMPLXF(copysignf(0, x * (y - y)), y - y);
 
        if (iy == 0 && ix >= 0x7f800000) {
                if ((hx & 0x7fffff) == 0)
-                       return cpackf(x, y);
-               return cpackf(x, copysignf(0, y));
+                       return CMPLXF(x, y);
+               return CMPLXF(x, copysignf(0, y));
        }
 
        if (ix < 0x7f800000 && iy >= 0x7f800000)
-               return cpackf(y - y, x * (y - y));
+               return CMPLXF(y - y, x * (y - y));
 
        if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) {
                if (iy >= 0x7f800000)
-                       return cpackf(x * x, x * (y - y));
-               return cpackf(x * cosf(y), INFINITY * sinf(y));
+                       return CMPLXF(x * x, x * (y - y));
+               return CMPLXF(x * cosf(y), INFINITY * sinf(y));
        }
 
-       return cpackf((x * x) * (y - y), (x + x) * (y - y));
+       return CMPLXF((x * x) * (y - y), (x + x) * (y - y));
 }
index 4ad8674..4e9f86c 100644 (file)
@@ -8,7 +8,7 @@ long double complex csinl(long double complex z)
 #else
 long double complex csinl(long double complex z)
 {
-       z = csinhl(cpackl(-cimagl(z), creall(z)));
-       return cpackl(cimagl(z), -creall(z));
+       z = csinhl(CMPLXL(-cimagl(z), creall(z)));
+       return CMPLXL(cimagl(z), -creall(z));
 }
 #endif
index 21fb879..8a2ba60 100644 (file)
@@ -51,12 +51,12 @@ double complex csqrt(double complex z)
 
        /* Handle special cases. */
        if (z == 0)
-               return cpack(0, b);
+               return CMPLX(0, b);
        if (isinf(b))
-               return cpack(INFINITY, b);
+               return CMPLX(INFINITY, b);
        if (isnan(a)) {
                t = (b - b) / (b - b);  /* raise invalid if b is not a NaN */
-               return cpack(a, t);   /* return NaN + NaN i */
+               return CMPLX(a, t);   /* return NaN + NaN i */
        }
        if (isinf(a)) {
                /*
@@ -66,9 +66,9 @@ double complex csqrt(double complex z)
                 * csqrt(-inf + y i)   = 0   +  inf i
                 */
                if (signbit(a))
-                       return cpack(fabs(b - b), copysign(a, b));
+                       return CMPLX(fabs(b - b), copysign(a, b));
                else
-                       return cpack(a, copysign(b - b, b));
+                       return CMPLX(a, copysign(b - b, b));
        }
        /*
         * The remaining special case (b is NaN) is handled just fine by
@@ -87,10 +87,10 @@ double complex csqrt(double complex z)
        /* Algorithm 312, CACM vol 10, Oct 1967. */
        if (a >= 0) {
                t = sqrt((a + hypot(a, b)) * 0.5);
-               result = cpack(t, b / (2 * t));
+               result = CMPLX(t, b / (2 * t));
        } else {
                t = sqrt((-a + hypot(a, b)) * 0.5);
-               result = cpack(fabs(b) / (2 * t), copysign(t, b));
+               result = CMPLX(fabs(b) / (2 * t), copysign(t, b));
        }
 
        /* Rescale. */
index 16487c2..ab5102f 100644 (file)
@@ -43,12 +43,12 @@ float complex csqrtf(float complex z)
 
        /* Handle special cases. */
        if (z == 0)
-               return cpackf(0, b);
+               return CMPLXF(0, b);
        if (isinf(b))
-               return cpackf(INFINITY, b);
+               return CMPLXF(INFINITY, b);
        if (isnan(a)) {
                t = (b - b) / (b - b);  /* raise invalid if b is not a NaN */
-               return cpackf(a, t);  /* return NaN + NaN i */
+               return CMPLXF(a, t);  /* return NaN + NaN i */
        }
        if (isinf(a)) {
                /*
@@ -58,9 +58,9 @@ float complex csqrtf(float complex z)
                 * csqrtf(-inf + y i)   = 0   +  inf i
                 */
                if (signbit(a))
-                       return cpackf(fabsf(b - b), copysignf(a, b));
+                       return CMPLXF(fabsf(b - b), copysignf(a, b));
                else
-                       return cpackf(a, copysignf(b - b, b));
+                       return CMPLXF(a, copysignf(b - b, b));
        }
        /*
         * The remaining special case (b is NaN) is handled just fine by
@@ -74,9 +74,9 @@ float complex csqrtf(float complex z)
         */
        if (a >= 0) {
                t = sqrt((a + hypot(a, b)) * 0.5);
-               return cpackf(t, b / (2.0 * t));
+               return CMPLXF(t, b / (2.0 * t));
        } else {
                t = sqrt((-a + hypot(a, b)) * 0.5);
-               return cpackf(fabsf(b) / (2.0 * t), copysignf(t, b));
+               return CMPLXF(fabsf(b) / (2.0 * t), copysignf(t, b));
        }
 }
index 4741a4d..c092637 100644 (file)
@@ -4,6 +4,6 @@
 
 double complex ctan(double complex z)
 {
-       z = ctanh(cpack(-cimag(z), creal(z)));
-       return cpack(cimag(z), -creal(z));
+       z = ctanh(CMPLX(-cimag(z), creal(z)));
+       return CMPLX(cimag(z), -creal(z));
 }
index 9bbeb05..009b192 100644 (file)
@@ -2,6 +2,6 @@
 
 float complex ctanf(float complex z)
 {
-       z = ctanhf(cpackf(-cimagf(z), crealf(z)));
-       return cpackf(cimagf(z), -crealf(z));
+       z = ctanhf(CMPLXF(-cimagf(z), crealf(z)));
+       return CMPLXF(cimagf(z), -crealf(z));
 }
index dd569fc..0461050 100644 (file)
@@ -95,9 +95,9 @@ double complex ctanh(double complex z)
         */
        if (ix >= 0x7ff00000) {
                if ((ix & 0xfffff) | lx)        /* x is NaN */
-                       return cpack(x, (y == 0 ? y : x * y));
+                       return CMPLX(x, (y == 0 ? y : x * y));
                SET_HIGH_WORD(x, hx - 0x40000000);      /* x = copysign(1, x) */
-               return cpack(x, copysign(0, isinf(y) ? y : sin(y) * cos(y)));
+               return CMPLX(x, copysign(0, isinf(y) ? y : sin(y) * cos(y)));
        }
 
        /*
@@ -105,7 +105,7 @@ double complex ctanh(double complex z)
         * ctanh(x +- i Inf) = NaN + i NaN
         */
        if (!isfinite(y))
-               return cpack(y - y, y - y);
+               return CMPLX(y - y, y - y);
 
        /*
         * ctanh(+-huge + i +-y) ~= +-1 +- i 2sin(2y)/exp(2x), using the
@@ -114,7 +114,7 @@ double complex ctanh(double complex z)
         */
        if (ix >= 0x40360000) { /* x >= 22 */
                double exp_mx = exp(-fabs(x));
-               return cpack(copysign(1, x), 4 * sin(y) * cos(y) * exp_mx * exp_mx);
+               return CMPLX(copysign(1, x), 4 * sin(y) * cos(y) * exp_mx * exp_mx);
        }
 
        /* Kahan's algorithm */
@@ -123,5 +123,5 @@ double complex ctanh(double complex z)
        s = sinh(x);
        rho = sqrt(1 + s * s);  /* = cosh(x) */
        denom = 1 + beta * s * s;
-       return cpack((beta * rho * s) / denom, t / denom);
+       return CMPLX((beta * rho * s) / denom, t / denom);
 }
index 7d74613..a7e1a5f 100644 (file)
@@ -44,17 +44,17 @@ float complex ctanhf(float complex z)
 
        if (ix >= 0x7f800000) {
                if (ix & 0x7fffff)
-                       return cpackf(x, (y == 0 ? y : x * y));
+                       return CMPLXF(x, (y == 0 ? y : x * y));
                SET_FLOAT_WORD(x, hx - 0x40000000);
-               return cpackf(x, copysignf(0, isinf(y) ? y : sinf(y) * cosf(y)));
+               return CMPLXF(x, copysignf(0, isinf(y) ? y : sinf(y) * cosf(y)));
        }
 
        if (!isfinite(y))
-               return cpackf(y - y, y - y);
+               return CMPLXF(y - y, y - y);
 
        if (ix >= 0x41300000) { /* x >= 11 */
                float exp_mx = expf(-fabsf(x));
-               return cpackf(copysignf(1, x), 4 * sinf(y) * cosf(y) * exp_mx * exp_mx);
+               return CMPLXF(copysignf(1, x), 4 * sinf(y) * cosf(y) * exp_mx * exp_mx);
        }
 
        t = tanf(y);
@@ -62,5 +62,5 @@ float complex ctanhf(float complex z)
        s = sinhf(x);
        rho = sqrtf(1 + s * s);
        denom = 1 + beta * s * s;
-       return cpackf((beta * rho * s) / denom, t / denom);
+       return CMPLXF((beta * rho * s) / denom, t / denom);
 }
index 4b4c99b..ac1c3e0 100644 (file)
@@ -8,7 +8,7 @@ long double complex ctanl(long double complex z)
 #else
 long double complex ctanl(long double complex z)
 {
-       z = ctanhl(cpackl(-cimagl(z), creall(z)));
-       return cpackl(cimagl(z), -creall(z));
+       z = ctanhl(CMPLXL(-cimagl(z), creall(z)));
+       return CMPLXL(cimagl(z), -creall(z));
 }
 #endif
index f77599b..b2dfd25 100644 (file)
@@ -19,7 +19,7 @@ int fetestexcept(int mask)
 
 int fegetround(void)
 {
-       return 0;
+       return FE_TONEAREST;
 }
 
 int fesetround(int r)
index 50cef8e..f45ed7c 100644 (file)
@@ -2,6 +2,7 @@
 
 int feupdateenv(const fenv_t *envp)
 {
+       #pragma STDC FENV_ACCESS ON
        int ex = fetestexcept(FE_ALL_EXCEPT);
        fesetenv(envp);
        feraiseexcept(ex);
index a71c4c0..46c4b56 100644 (file)
@@ -157,38 +157,23 @@ long double __tanl(long double, long double, int);
 long double __polevll(long double, const long double *, int);
 long double __p1evll(long double, const long double *, int);
 
-// FIXME: not needed when -fexcess-precision=standard is supported (>=gcc4.5)
-/*
- * Attempt to get strict C99 semantics for assignment with non-C99 compilers.
- */
-#if 1
+#if 0
+/* Attempt to get strict C99 semantics for assignment with non-C99 compilers. */
 #define STRICT_ASSIGN(type, lval, rval) do {    \
         volatile type __v = (rval);             \
         (lval) = __v;                           \
 } while (0)
 #else
+/* Should work with -fexcess-precision=standard (>=gcc-4.5) or -ffloat-store */
 #define STRICT_ASSIGN(type, lval, rval) ((lval) = (type)(rval))
 #endif
 
-
 /* complex */
 
-union dcomplex {
-       double complex z;
-       double a[2];
-};
-union fcomplex {
-       float complex z;
-       float a[2];
-};
-union lcomplex {
-       long double complex z;
-       long double a[2];
-};
-
-/* x + y*I is not supported properly by gcc */
-#define cpack(x,y) ((union dcomplex){.a={(x),(y)}}.z)
-#define cpackf(x,y) ((union fcomplex){.a={(x),(y)}}.z)
-#define cpackl(x,y) ((union lcomplex){.a={(x),(y)}}.z)
+#ifndef CMPLX
+#define CMPLX(x, y) __CMPLX(x, y, double)
+#define CMPLXF(x, y) __CMPLX(x, y, float)
+#define CMPLXL(x, y) __CMPLX(x, y, long double)
+#endif
 
 #endif
index a821842..a51330e 100644 (file)
@@ -28,9 +28,8 @@
 #include "__invtrigl.h"
 
 #if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
-/*
- * asinl() and acosl()
- */
+
+/* coefficients used in asinl() and acosl() */
 const long double
 pS0 =  1.66666666666666666631e-01L,
 pS1 = -4.16313987993683104320e-01L,
@@ -45,38 +44,9 @@ qS3 = -1.68285799854822427013e+00L,
 qS4 =  3.90699412641738801874e-01L,
 qS5 = -3.14365703596053263322e-02L;
 
-/*
- * atanl()
- */
-const long double atanhi[] = {
-        4.63647609000806116202e-01L,
-        7.85398163397448309628e-01L,
-        9.82793723247329067960e-01L,
-        1.57079632679489661926e+00L,
-};
-
-const long double atanlo[] = {
-        1.18469937025062860669e-20L,
-       -1.25413940316708300586e-20L,
-        2.55232234165405176172e-20L,
-       -2.50827880633416601173e-20L,
-};
-
-const long double aT[] = {
-        3.33333333333333333017e-01L,
-       -1.99999999999999632011e-01L,
-        1.42857142857046531280e-01L,
-       -1.11111111100562372733e-01L,
-        9.09090902935647302252e-02L,
-       -7.69230552476207730353e-02L,
-        6.66661718042406260546e-02L,
-       -5.88158892835030888692e-02L,
-        5.25499891539726639379e-02L,
-       -4.70119845393155721494e-02L,
-        4.03539201366454414072e-02L,
-       -2.91303858419364158725e-02L,
-        1.24822046299269234080e-02L,
-};
-
+const long double pi_hi = 3.1415926535897932384626433832795L;
 const long double pi_lo = -5.01655761266833202345e-20L;
+const long double pio2_hi = 1.57079632679489661926L;
+const long double pio2_lo = -2.50827880633416601173e-20L;
+
 #endif
index c3ad3c4..22748b6 100644 (file)
 #define BIAS            (LDBL_MAX_EXP - 1)
 #define MANH_SIZE       LDBL_MANH_SIZE
 
-/* Approximation thresholds. */
-#define ASIN_LINEAR     (BIAS - 32)     /* 2**-32 */
-#define ACOS_CONST      (BIAS - 65)     /* 2**-65 */
-#define ATAN_CONST      (BIAS + 65)     /* 2**65 */
-#define ATAN_LINEAR     (BIAS - 32)     /* 2**-32 */
-
-/* 0.95 */
-#define THRESH  ((0xe666666666666666ULL>>(64-(MANH_SIZE-1)))|LDBL_NBIT)
-
 /* Constants shared by the long double inverse trig functions. */
 #define pS0     __pS0
 #define pS1     __pS1
 #define qS3     __qS3
 #define qS4     __qS4
 #define qS5     __qS5
-#define atanhi  __atanhi
-#define atanlo  __atanlo
-#define aT      __aT
+#define pi_hi   __pi_hi
 #define pi_lo   __pi_lo
+#define pio2_hi __pio2_hi
+#define pio2_lo __pio2_lo
 
-#define pio2_hi atanhi[3]
-#define pio2_lo atanlo[3]
-#define pio4_hi atanhi[1]
-
-#ifdef STRUCT_DECLS
-typedef struct longdouble {
-       uint64_t mant;
-       uint16_t expsign;
-} LONGDOUBLE;
-#else
-typedef long double LONGDOUBLE;
-#endif
-
-extern const LONGDOUBLE pS0, pS1, pS2, pS3, pS4, pS5, pS6;
-extern const LONGDOUBLE qS1, qS2, qS3, qS4, qS5;
-extern const LONGDOUBLE atanhi[], atanlo[], aT[];
-extern const LONGDOUBLE pi_lo;
-
-#ifndef STRUCT_DECLS
-static inline long double
-P(long double x)
-{
-       return (x * (pS0 + x * (pS1 + x * (pS2 + x * (pS3 + x * \
-               (pS4 + x * (pS5 + x * pS6)))))));
-}
-
-static inline long double
-Q(long double x)
-{
-       return (1.0 + x * (qS1 + x * (qS2 + x * (qS3 + x * (qS4 + x * qS5)))));
-}
+extern const long double pS0, pS1, pS2, pS3, pS4, pS5, pS6;
+extern const long double qS1, qS2, qS3, qS4, qS5;
+extern const long double pi_hi, pi_lo, pio2_hi, pio2_lo;
 
-static inline long double
-T_even(long double x)
+static long double P(long double x)
 {
-       return (aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] + x * \
-               (aT[8] + x * (aT[10] + x * aT[12]))))));
+       return x * (pS0 + x * (pS1 + x * (pS2 + x * (pS3 +
+               x * (pS4 + x * (pS5 + x * pS6))))));
 }
 
-static inline long double
-T_odd(long double x)
+static long double Q(long double x)
 {
-       return (aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] + x * \
-               (aT[9] + x * aT[11])))));
+       return 1.0 + x * (qS1 + x * (qS2 + x * (qS3 + x * (qS4 + x * qS5))));
 }
-#endif
 
 #endif
index 54d266e..0eb15be 100644 (file)
@@ -38,6 +38,7 @@
 static const double
 pi      = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
 pio2_hi = 1.57079632679489655800e+00; /* 0x3FF921FB, 0x54442D18 */
+// FIXME
 static const volatile double
 pio2_lo = 6.12323399573676603587e-17; /* 0x3C91A626, 0x33145C07 */
 static const double
index cc56533..83857d4 100644 (file)
@@ -23,9 +23,7 @@ long double acosl(long double x)
 }
 #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
 #include "__invtrigl.h"
-
-static const long double
-pi = 3.14159265358979323846264338327950280e+00L;
+#define ACOS_CONST      (BIAS - 65)     /* 2**-65 */
 
 long double acosl(long double x)
 {
@@ -41,7 +39,8 @@ long double acosl(long double x)
                        if (expsign > 0)
                                return 0.0;  /* acos(1) = 0 */
                        else
-                               return pi + 2.0 * pio2_lo;  /* acos(-1)= pi */
+                               // FIXME
+                               return pi_hi + 2.0 * pio2_lo;  /* acos(-1)= pi */
                }
                return (x - x) / (x - x);  /* acos(|x|>1) is NaN */
        }
@@ -60,7 +59,7 @@ long double acosl(long double x)
                s = sqrtl(z);
                r = p / q;
                w = r * s - pio2_lo;
-               return pi - 2.0 * (s + w);
+               return pi_hi - 2.0 * (s + w);
        } else {                   /* x > 0.5 */
                z = (1.0 - x) * 0.5;
                s = sqrtl(z);
index ddd807e..7572767 100644 (file)
@@ -24,6 +24,10 @@ long double asinl(long double x)
 #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
 #include "__invtrigl.h"
 static const long double huge = 1.000e+300;
+static const long double pio4_hi = 7.85398163397448309628e-01L;
+#define ASIN_LINEAR     (BIAS - 32)     /* 2**-32 */
+/* 0.95 */
+#define THRESH  ((0xe666666666666666ULL>>(64-(MANH_SIZE-1)))|LDBL_NBIT)
 
 long double asinl(long double x)
 {
index 143c383..825a38f 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "libm.h"
 
+// FIXME
 static const volatile double
 tiny  = 1.0e-300;
 static const double
index 0fc901c..45cbfcc 100644 (file)
@@ -24,10 +24,8 @@ long double atan2l(long double y, long double x)
 }
 #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
 #include "__invtrigl.h"
-static const volatile long double
-tiny = 1.0e-300;
-static const long double
-pi = 3.14159265358979323846264338327950280e+00L;
+// FIXME:
+static const volatile long double tiny = 1.0e-300;
 
 long double atan2l(long double y, long double x)
 {
@@ -55,9 +53,9 @@ long double atan2l(long double y, long double x)
        if (expty==0 && ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl)==0) {
                switch(m) {
                case 0:
-               case 1: return y;        /* atan(+-0,+anything)=+-0 */
-               case 2: return  pi+tiny; /* atan(+0,-anything) = pi */
-               case 3: return -pi-tiny; /* atan(-0,-anything) =-pi */
+               case 1: return y;           /* atan(+-0,+anything)=+-0 */
+               case 2: return  pi_hi+tiny; /* atan(+0,-anything) = pi */
+               case 3: return -pi_hi-tiny; /* atan(-0,-anything) =-pi */
                }
        }
        /* when x = 0 */
@@ -69,15 +67,15 @@ long double atan2l(long double y, long double x)
                        switch(m) {
                        case 0: return  pio2_hi*0.5+tiny; /* atan(+INF,+INF) */
                        case 1: return -pio2_hi*0.5-tiny; /* atan(-INF,+INF) */
-                       case 2: return  1.5*pio2_hi+tiny; /*atan(+INF,-INF)*/
-                       case 3: return -1.5*pio2_hi-tiny; /*atan(-INF,-INF)*/
+                       case 2: return  1.5*pio2_hi+tiny; /* atan(+INF,-INF) */
+                       case 3: return -1.5*pio2_hi-tiny; /* atan(-INF,-INF) */
                        }
                } else {
                        switch(m) {
-                       case 0: return  0.0;     /* atan(+...,+INF) */
-                       case 1: return -0.0;     /* atan(-...,+INF) */
-                       case 2: return  pi+tiny; /* atan(+...,-INF) */
-                       case 3: return -pi-tiny; /* atan(-...,-INF) */
+                       case 0: return  0.0;        /* atan(+...,+INF) */
+                       case 1: return -0.0;        /* atan(-...,+INF) */
+                       case 2: return  pi_hi+tiny; /* atan(+...,-INF) */
+                       case 3: return -pi_hi-tiny; /* atan(-...,-INF) */
                        }
                }
        }
@@ -95,11 +93,11 @@ long double atan2l(long double y, long double x)
        else                     /* safe to do y/x */
                z = atanl(fabsl(y/x));
        switch (m) {
-       case 0: return z;              /* atan(+,+) */
-       case 1: return -z;             /* atan(-,+) */
-       case 2: return pi - (z-pi_lo); /* atan(+,-) */
+       case 0: return z;               /* atan(+,+) */
+       case 1: return -z;              /* atan(-,+) */
+       case 2: return pi_hi-(z-pi_lo); /* atan(+,-) */
        default: /* case 3 */
-               return (z-pi_lo) - pi; /* atan(-,-) */
+               return (z-pi_lo)-pi_hi; /* atan(-,-) */
        }
 }
 #endif
index 36072c1..33ecff0 100644 (file)
@@ -23,8 +23,53 @@ long double atanl(long double x)
 }
 #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
 #include "__invtrigl.h"
+
+#define ATAN_CONST      (BIAS + 65)     /* 2**65 */
+#define ATAN_LINEAR     (BIAS - 32)     /* 2**-32 */
 static const long double huge = 1.0e300;
 
+static const long double atanhi[] = {
+        4.63647609000806116202e-01L,
+        7.85398163397448309628e-01L,
+        9.82793723247329067960e-01L,
+        1.57079632679489661926e+00L,
+};
+
+static const long double atanlo[] = {
+        1.18469937025062860669e-20L,
+       -1.25413940316708300586e-20L,
+        2.55232234165405176172e-20L,
+       -2.50827880633416601173e-20L,
+};
+
+static const long double aT[] = {
+        3.33333333333333333017e-01L,
+       -1.99999999999999632011e-01L,
+        1.42857142857046531280e-01L,
+       -1.11111111100562372733e-01L,
+        9.09090902935647302252e-02L,
+       -7.69230552476207730353e-02L,
+        6.66661718042406260546e-02L,
+       -5.88158892835030888692e-02L,
+        5.25499891539726639379e-02L,
+       -4.70119845393155721494e-02L,
+        4.03539201366454414072e-02L,
+       -2.91303858419364158725e-02L,
+        1.24822046299269234080e-02L,
+};
+
+static long double T_even(long double x)
+{
+       return aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] +
+               x * (aT[8] + x * (aT[10] + x * aT[12])))));
+}
+
+static long double T_odd(long double x)
+{
+       return aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] +
+               x * (aT[9] + x * aT[11]))));
+}
+
 long double atanl(long double x)
 {
        union IEEEl2bits u;
index 4b2b7ef..22a4636 100644 (file)
@@ -5,8 +5,8 @@
 long double exp10l(long double x)
 {
        static const long double p10[] = {
-               1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10,
-               1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,
+               1e-15L, 1e-14L, 1e-13L, 1e-12L, 1e-11L, 1e-10L,
+               1e-9L, 1e-8L, 1e-7L, 1e-6L, 1e-5L, 1e-4L, 1e-3L, 1e-2L, 1e-1L,
                1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
                1e10, 1e11, 1e12, 1e13, 1e14, 1e15
        };
index ca0d141..21a86c0 100644 (file)
  *
  *                      Relative error:
  * arithmetic   domain     # trials      peak         rms
- *    IEEE    -45,+MAXLOG   200,000     1.2e-19     2.5e-20
- *
- * ERROR MESSAGES:
- *
- *   message         condition      value returned
- * expm1l overflow   x > MAXLOG         MAXNUM
- *
+ *    IEEE    -45,+maxarg   200,000     1.2e-19     2.5e-20
  */
 
 #include "libm.h"
@@ -61,7 +55,6 @@ long double expm1l(long double x)
        return expm1(x);
 }
 #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
-static const long double MAXLOGL = 1.1356523406294143949492E4L;
 
 /* exp(x) - 1 = x + 0.5 x^2 + x^3 P(x)/Q(x)
    -.5 ln 2  <  x  <  .5 ln 2
@@ -83,19 +76,20 @@ C1 = 6.93145751953125E-1L,
 C2 = 1.428606820309417232121458176568075500134E-6L,
 /* ln 2^-65 */
 minarg = -4.5054566736396445112120088E1L,
-huge = 0x1p10000L;
+/* ln 2^16384 */
+maxarg = 1.1356523406294143949492E4L;
 
 long double expm1l(long double x)
 {
        long double px, qx, xx;
        int k;
 
-       /* Overflow.  */
-       if (x > MAXLOGL)
-               return huge*huge;  /* overflow */
+       if (isnan(x))
+               return x;
+       if (x > maxarg)
+               return x*0x1p16383L; /* overflow, unless x==inf */
        if (x == 0.0)
                return x;
-       /* Minimum value.*/
        if (x < minarg)
                return -1.0;
 
index 7076d4b..17f1cdc 100644 (file)
@@ -89,6 +89,7 @@ static int getexp(long double x)
 
 double fma(double x, double y, double z)
 {
+       #pragma STDC FENV_ACCESS ON
        long double hi, lo1, lo2, xy;
        int round, ez, exy;
 
@@ -306,6 +307,7 @@ static inline struct dd dd_mul(double a, double b)
  */
 double fma(double x, double y, double z)
 {
+       #pragma STDC FENV_ACCESS ON
        double xs, ys, zs, adj;
        struct dd xy, r;
        int oround;
index cc427fb..a1c7f4f 100644 (file)
@@ -37,6 +37,7 @@
  */
 float fmaf(float x, float y, float z)
 {
+       #pragma STDC FENV_ACCESS ON
        double xy, result;
        uint32_t hr, lr;
 
index be64f14..ccbe434 100644 (file)
@@ -162,6 +162,7 @@ static inline struct dd dd_mul(long double a, long double b)
  */
 long double fmal(long double x, long double y, long double z)
 {
+       #pragma STDC FENV_ACCESS ON
        long double xs, ys, zs, adj;
        struct dd xy, r;
        int oround;
index ba4c757..9a4cbdb 100644 (file)
@@ -117,12 +117,7 @@ double hypot(double x, double y)
                t2 = a - t1;
                w  = sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
        }
-       if (k != 0) {
-               uint32_t high;
-               t1 = 1.0;
-               GET_HIGH_WORD(high, t1);
-               SET_HIGH_WORD(t1, high+(k<<20));
-               return t1*w;
-       }
+       if (k)
+               w = scalbn(w, k);
        return w;
 }
index 9fd77e6..4d80178 100644 (file)
@@ -80,9 +80,7 @@ float hypotf(float x, float y)
                t2 = a - t1;
                w  = sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b)));
        }
-       if (k != 0) {
-               SET_FLOAT_WORD(t1, 0x3f800000+(k<<23));
-               return t1*w;
-       }
+       if (k)
+               w = scalbnf(w, k);
        return w;
 }
index 0a3a6a4..5a1819d 100644 (file)
@@ -8,13 +8,17 @@ int ilogb(double x)
 
        if (!e) {
                u.bits <<= 12;
-               if (u.bits == 0)
+               if (u.bits == 0) {
+                       FORCE_EVAL(0/0.0f);
                        return FP_ILOGB0;
+               }
                /* subnormal x */
                for (e = -0x3ff; u.bits < (uint64_t)1<<63; e--, u.bits<<=1);
                return e;
        }
-       if (e == 0x7ff)
+       if (e == 0x7ff) {
+               FORCE_EVAL(0/0.0f);
                return u.bits<<12 ? FP_ILOGBNAN : INT_MAX;
+       }
        return e - 0x3ff;
 }
index 272cbda..42cd62e 100644 (file)
@@ -8,13 +8,17 @@ int ilogbf(float x)
 
        if (!e) {
                u.bits <<= 9;
-               if (u.bits == 0)
+               if (u.bits == 0) {
+                       FORCE_EVAL(0/0.0f);
                        return FP_ILOGB0;
+               }
                /* subnormal x */
                for (e = -0x7f; u.bits < (uint32_t)1<<31; e--, u.bits<<=1);
                return e;
        }
-       if (e == 0xff)
+       if (e == 0xff) {
+               FORCE_EVAL(0/0.0f);
                return u.bits<<9 ? FP_ILOGBNAN : INT_MAX;
+       }
        return e - 0x7f;
 }
index ed9ddcb..1512934 100644 (file)
@@ -14,15 +14,19 @@ int ilogbl(long double x)
        int e = u.bits.exp;
 
        if (!e) {
-               if (m == 0)
+               if (m == 0) {
+                       FORCE_EVAL(0/0.0f);
                        return FP_ILOGB0;
+               }
                /* subnormal x */
                for (e = -0x3fff+1; m < (uint64_t)1<<63; e--, m<<=1);
                return e;
        }
-       if (e == 0x7fff)
+       if (e == 0x7fff) {
+               FORCE_EVAL(0/0.0f);
                /* in ld80 msb is set in inf */
                return m & (uint64_t)-1>>1 ? FP_ILOGBNAN : INT_MAX;
+       }
        return e - 0x3fff;
 }
 #endif
index 32bb8b0..3449f6f 100644 (file)
@@ -18,6 +18,7 @@ raises inexact (with tonearest or upward rounding mode)
 */
 long long llrintl(long double x)
 {
+       #pragma STDC FENV_ACCESS ON
        int e;
 
        e = fetestexcept(FE_INEXACT);
index 1400d36..edb48df 100644 (file)
  *                      Relative error:
  * arithmetic   domain     # trials      peak         rms
  *    IEEE     -1.0, 9.0    100000      8.2e-20    2.5e-20
- *
- * ERROR MESSAGES:
- *
- * log singularity:  x-1 = 0; returns -INFINITY
- * log domain:       x-1 < 0; returns NAN
  */
 
 #include "libm.h"
@@ -123,8 +118,8 @@ long double log1pl(long double xm1)
        /* Test for domain errors.  */
        if (x <= 0.0) {
                if (x == 0.0)
-                       return -INFINITY;
-               return NAN;
+                       return -1/x; /* -inf with divbyzero */
+               return 0/0.0f; /* nan with invalid */
        }
 
        /* Separate mantissa from exponent.
index 8ebce9c..345b395 100644 (file)
  * In the tests over the interval exp(+-10000), the logarithms
  * of the random arguments were uniformly distributed over
  * [-10000, +10000].
- *
- * ERROR MESSAGES:
- *
- * log singularity:  x = 0; returns -INFINITY
- * log domain:       x < 0; returns NAN
  */
 
 #include "libm.h"
@@ -113,8 +108,7 @@ static const long double S[4] = {
 
 long double log2l(long double x)
 {
-       volatile long double z;
-       long double y;
+       long double y, z;
        int e;
 
        if (isnan(x))
@@ -123,8 +117,8 @@ long double log2l(long double x)
                return x;
        if (x <= 0.0) {
                if (x == 0.0)
-                       return -INFINITY;
-               return NAN;
+                       return -1/(x+0); /* -inf with divbyzero */
+               return 0/0.0f; /* nan with invalid */
        }
 
        /* separate mantissa from exponent */
index f7cd761..624425a 100644 (file)
@@ -1,20 +1,17 @@
-#include <limits.h>
 #include "libm.h"
 
 /*
 special cases:
-       logb(+-0) = -inf
+       logb(+-0) = -inf, and raise divbyzero
        logb(+-inf) = +inf
        logb(nan) = nan
-these are calculated at runtime to raise fp exceptions
 */
 
-double logb(double x) {
-       int i = ilogb(x);
-
-       if (i == FP_ILOGB0)
-               return -1.0/fabs(x);
-       if (i == FP_ILOGBNAN || i == INT_MAX)
+double logb(double x)
+{
+       if (!isfinite(x))
                return x * x;
-       return i;
+       if (x == 0)
+               return -1/(x+0);
+       return ilogb(x);
 }
index 934827f..950d356 100644 (file)
@@ -1,12 +1,10 @@
-#include <limits.h>
 #include "libm.h"
 
-float logbf(float x) {
-       int i = ilogbf(x);
-
-       if (i == FP_ILOGB0)
-               return -1.0f/fabsf(x);
-       if (i == FP_ILOGBNAN || i == INT_MAX)
+float logbf(float x)
+{
+       if (!isfinite(x))
                return x * x;
-       return i;
+       if (x == 0)
+               return -1/(x+0);
+       return ilogbf(x);
 }
index 5d04abd..f385074 100644 (file)
@@ -1,4 +1,3 @@
-#include <limits.h>
 #include "libm.h"
 #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
 long double logbl(long double x)
@@ -8,12 +7,10 @@ long double logbl(long double x)
 #else
 long double logbl(long double x)
 {
-       int i = ilogbl(x);
-
-       if (i == FP_ILOGB0)
-               return -1.0/fabsl(x);
-       if (i == FP_ILOGBNAN || i == INT_MAX)
+       if (!isfinite(x))
                return x * x;
-       return i;
+       if (x == 0)
+               return -1/(x+0);
+       return ilogbl(x);
 }
 #endif
index ffd8103..ef2b551 100644 (file)
  * In the tests over the interval exp(+-10000), the logarithms
  * of the random arguments were uniformly distributed over
  * [-10000, +10000].
- *
- * ERROR MESSAGES:
- *
- * log singularity:  x = 0; returns -INFINITY
- * log domain:       x < 0; returns NAN
  */
 
 #include "libm.h"
@@ -121,8 +116,8 @@ long double logl(long double x)
                return x;
        if (x <= 0.0) {
                if (x == 0.0)
-                       return -INFINITY;
-               return NAN;
+                       return -1/(x+0); /* -inf with divbyzero */
+               return 0/0.0f; /* nan with invalid */
        }
 
        /* separate mantissa from exponent */
index 6709183..bdca8b7 100644 (file)
@@ -28,6 +28,7 @@ as a double.
 #if LONG_MAX < 1U<<53 && defined(FE_INEXACT)
 long lrint(double x)
 {
+       #pragma STDC FENV_ACCESS ON
        int e;
 
        e = fetestexcept(FE_INEXACT);
index 5eb1ba7..b2a8106 100644 (file)
@@ -18,6 +18,7 @@ raises inexact (with tonearest or upward rounding mode)
 */
 long lrintl(long double x)
 {
+       #pragma STDC FENV_ACCESS ON
        int e;
 
        e = fetestexcept(FE_INEXACT);
index de45069..8f337ef 100644 (file)
@@ -1,5 +1,4 @@
-#include <math.h>
-#include <stdint.h>
+#include "libm.h"
 
 double modf(double x, double *iptr)
 {
@@ -33,5 +32,6 @@ double modf(double x, double *iptr)
        }
        u.n &= ~mask;
        *iptr = u.x;
-       return x - *iptr;
+       STRICT_ASSIGN(double, x, x - *iptr);
+       return x;
 }
index 84d0b82..90caf31 100644 (file)
@@ -1,5 +1,4 @@
-#include <math.h>
-#include <stdint.h>
+#include "libm.h"
 
 float modff(float x, float *iptr)
 {
@@ -33,5 +32,6 @@ float modff(float x, float *iptr)
        }
        u.n &= ~mask;
        *iptr = u.x;
-       return x - *iptr;
+       STRICT_ASSIGN(float, x, x - *iptr);
+       return x;
 }
index 7a4c58c..f4e8aac 100644 (file)
@@ -6,6 +6,7 @@
 double nearbyint(double x)
 {
 #ifdef FE_INEXACT
+       #pragma STDC FENV_ACCESS ON
        int e;
 
        e = fetestexcept(FE_INEXACT);
index 39c3d73..092e9ff 100644 (file)
@@ -4,6 +4,7 @@
 float nearbyintf(float x)
 {
 #ifdef FE_INEXACT
+       #pragma STDC FENV_ACCESS ON
        int e;
 
        e = fetestexcept(FE_INEXACT);
index 0ff4b1f..8285249 100644 (file)
@@ -11,6 +11,7 @@ long double nearbyintl(long double x)
 long double nearbyintl(long double x)
 {
 #ifdef FE_INEXACT
+       #pragma STDC FENV_ACCESS ON
        int e;
 
        e = fetestexcept(FE_INEXACT);
index a3b42c9..9ee8251 100644 (file)
@@ -27,7 +27,7 @@ double nextafter(double x, double y)
        e = ux.bits >> 52 & 0x7ff;
        /* raise overflow if ux.value is infinite and x is finite */
        if (e == 0x7ff)
-               return x + x;
+               FORCE_EVAL(x+x);
        /* raise underflow if ux.value is subnormal or zero */
        if (e == 0)
                FORCE_EVAL(x*x + ux.value*ux.value);
index b703487..22b61dc 100644 (file)
@@ -26,7 +26,7 @@ float nextafterf(float x, float y)
        e = ux.bits & 0x7f800000;
        /* raise overflow if ux.value is infinite and x is finite */
        if (e == 0x7f800000)
-               return x + x;
+               FORCE_EVAL(x+x);
        /* raise underflow if ux.value is subnormal or zero */
        if (e == 0)
                FORCE_EVAL(x*x + ux.value*ux.value);
index 7355f2f..6f32eca 100644 (file)
@@ -36,7 +36,7 @@ double nexttoward(double x, long double y)
        e = ux.bits>>52 & 0x7ff;
        /* raise overflow if ux.value is infinite and x is finite */
        if (e == 0x7ff)
-               return x + x;
+               FORCE_EVAL(x+x);
        /* raise underflow if ux.value is subnormal or zero */
        if (e == 0)
                FORCE_EVAL(x*x + ux.value*ux.value);
index 8648be6..9a693b1 100644 (file)
@@ -28,7 +28,7 @@ float nexttowardf(float x, long double y)
        e = ux.bits & 0x7f800000;
        /* raise overflow if ux.value is infinite and x is finite */
        if (e == 0x7f800000)
-               return x + x;
+               FORCE_EVAL(x+x);
        /* raise underflow if ux.value is subnormal or zero */
        if (e == 0)
                FORCE_EVAL(x*x + ux.value*ux.value);
index c9c7af8..003141e 100644 (file)
@@ -10,8 +10,10 @@ double scalbn(double x, int n)
                if (n > 1023) {
                        x *= 0x1p1023;
                        n -= 1023;
-                       if (n > 1023)
-                               return x * 0x1p1023;
+                       if (n > 1023) {
+                               STRICT_ASSIGN(double, x, x * 0x1p1023);
+                               return x;
+                       }
                }
        } else if (n < -1022) {
                x *= 0x1p-1022;
@@ -19,10 +21,13 @@ double scalbn(double x, int n)
                if (n < -1022) {
                        x *= 0x1p-1022;
                        n += 1022;
-                       if (n < -1022)
-                               return x * 0x1p-1022;
+                       if (n < -1022) {
+                               STRICT_ASSIGN(double, x, x * 0x1p-1022);
+                               return x;
+                       }
                }
        }
        INSERT_WORDS(scale, (uint32_t)(0x3ff+n)<<20, 0);
-       return x * scale;
+       STRICT_ASSIGN(double, x, x * scale);
+       return x;
 }
index 243dafd..f94b5d5 100644 (file)
@@ -10,8 +10,10 @@ float scalbnf(float x, int n)
                if (n > 127) {
                        x *= 0x1p127f;
                        n -= 127;
-                       if (n > 127)
-                               return x * 0x1p127f;
+                       if (n > 127) {
+                               STRICT_ASSIGN(float, x, x * 0x1p127f);
+                               return x;
+                       }
                }
        } else if (n < -126) {
                x *= 0x1p-126f;
@@ -19,10 +21,13 @@ float scalbnf(float x, int n)
                if (n < -126) {
                        x *= 0x1p-126f;
                        n += 126;
-                       if (n < -126)
-                               return x * 0x1p-126f;
+                       if (n < -126) {
+                               STRICT_ASSIGN(float, x, x * 0x1p-126f);
+                               return x;
+                       }
                }
        }
        SET_FLOAT_WORD(scale, (uint32_t)(0x7f+n)<<23);
-       return x * scale;
+       STRICT_ASSIGN(float, x, x * scale);
+       return x;
 }