long double _IEEE_REMAINDER_R_D(double argx, long double argy) { union _ieee_ldouble { long double dword; long lword[2]; }; long double __remainder_d(long double x, long double y); long double x_val; int xfpclas = _fpclassify(argx); int yfpclas = _fpclassifyl(argy); if ((xfpclas == FP_NAN) || yfpclas == FP_ZERO) { union _ieee_ldouble x_val; int j; x_val.dword = _DBL_NaN; /* need to emit invalid exception */ j = FE_INVALID; feraiseexcept(j); return(x_val.dword); } x_val = (long double) argx; return(__remainder_d(x_val, argy)); }
long double _IEEE_REMAINDER_D_H(long double argx, float argy) { union _ieee_ldouble { long double ldword; long lword[2]; }; long double __remainder_d(long double x, long double y); long double y_val; int xfpclas = _fpclassifyl(argx); int yfpclas = _fpclassifyf(argy); if ((xfpclas == FP_INFINITE) || yfpclas == FP_ZERO) { union _ieee_ldouble xval; int j; xval.ldword = _DBL_NaN; /* need to emit invalid exception */ j = FE_INVALID; feraiseexcept(j); return(xval.ldword); } y_val = (long double) argy; return(__remainder_d(argx, y_val)); }
double _IEEE_EXPONENT_R_D(long double x) { /* Union defined to work with IEEE 128 bit floating point. */ union _ieee_ldouble { long double dword; long long lword[2]; struct { unsigned int sign : 1; unsigned int exponent : IEEE_128_EXPO_BITS; unsigned int mantissa_up : IEEE_128_MANT_BITS_UP; unsigned int mantissa_low : IEEE_128_MANT_BITS_LOW; } lparts; }; union _ieee_double { double dwrd; long long lwrd; struct { #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int mantissa : IEEE_64_MANT_BITS; unsigned int expon : IEEE_64_EXPO_BITS; unsigned int sgn : 1; #else unsigned int sgn : 1; unsigned int expon : IEEE_64_EXPO_BITS; unsigned int mantissa : IEEE_64_MANT_BITS; #endif } parts; }; switch (_fpclassifyl(x)) { case FP_NAN: { union _ieee_double x_val; x_val.lwrd = _SGL_NaN; return(x_val.dwrd); } case FP_INFINITE: { union _ieee_double x_val; x_val.lwrd = IEEE_64_INFINITY; return(x_val.dwrd); } case FP_NORMAL: { union _ieee_ldouble x_val; x_val.dword = x; return(x_val.lparts.exponent - IEEE_128_EXPO_BIAS); } case FP_SUBNORMAL: { union _ieee_ldouble x_val; int y; x_val.dword = x; /* _leadz returns number of zeros before first 1 * in mantissa. Add IEEE_128_EXPO_BITS to exclude * exponent bits, but count sign bit since * implicit bit needs to be counted. */ y = _leadz(x_val.lparts.mantissa_up); if (y == 64) /* entire upper mantissa is zero */ y += _leadz(x_val.lparts.mantissa_low); return(-IEEE_128_EXPO_BIAS - y + IEEE_128_EXPO_BITS); } case FP_ZERO: { int j; union _ieee_double x_val; /* raise divide-by-zero exception */ j = FE_DIVBYZERO; feraiseexcept(j); /* return negative infinity */ x_val.lwrd = IEEE_64_INFINITY; x_val.parts.sgn = 1; return(x_val.dwrd); } } }
long double _IEEE_NEXT_AFTER_D_D(long double x, long double y) { /* Union defined to work with IEEE 128 bit floating point. */ union _ieee_ldouble { long double dword; long lword[2]; struct { unsigned int sign : 1; unsigned int exponent : IEEE_128_EXPO_BITS; unsigned int mantissa_up : IEEE_128_MANT_BITS_UP; unsigned int mantissa_low : IEEE_128_MANT_BITS_LOW; } parts; }; int xfpclas = _fpclassifyl(x); int yfpclas = _fpclassifyl(y); if (xfpclas == FP_NAN) { return x; } else if (yfpclas == FP_NAN) { return y; } else if (xfpclas == FP_ZERO && yfpclas == FP_ZERO) { return x; } else if (x==y || xfpclas == FP_INFINITE) { return x; } else if (xfpclas == FP_ZERO) { union _ieee_ldouble x_val; x_val.dword = LDBL_MIN; x_val.parts.sign = x > y; /* return smallest normal number */ return(x_val.dword); } else { /* first argument is normal or denormal */ union _ieee_ldouble x_val, f; unsigned int add1,add2,add3; int j; int resfpclas; x_val.dword = x; f.dword = x; add3 = IEEE_128_MANTISSA_LOW; if (x > 0) { add1 = -0x1; add2 = 0x1; } else { add1 = 0x1; add2 = -0x1; } /* move one bit in the correct direction. ** Because of the way the implicit bit works, ** the exponent field is handled correctly. */ x_val.lword[1] += (x>y) ? add1 : add2; if ((f.parts.mantissa_low == add3) || (x_val.parts.mantissa_low == add3)) { x_val.lword[0] += (x>y) ? add1 : add2; } /* test for underflow or overflow */ if (_isnormall(x_val.dword)) return(x_val.dword); /* * Raise overflow exception for infinite result and * underflow exception for too small result. Raise * inexact exception for both cases. Allow subnormal * values to return without exception. */ resfpclas = _fpclassifyl(x_val.dword); if (resfpclas == FP_INFINITE) { j = FE_OVERFLOW; feraiseexcept(j); } else if (resfpclas == FP_ZERO) { j = FE_UNDERFLOW; feraiseexcept(j); } else { return(x_val.dword); } j = FE_INEXACT; feraiseexcept(j); return(x_val.dword); } }
double _IEEE_NEXT_AFTER_R_D(double x, long double y) { /* Union defined to work with IEEE 64-bit floating point. */ union _ieee_double { double dword; long long lword; struct { #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int mantissa : IEEE_64_MANT_BITS; unsigned int exponent : IEEE_64_EXPO_BITS; unsigned int sign : 1; #else unsigned int sign : 1; unsigned int exponent : IEEE_64_EXPO_BITS; unsigned int mantissa : IEEE_64_MANT_BITS; #endif } parts; }; int xfpclas = _fpclassify(x); int yfpclas = _fpclassifyl(y); if (xfpclas == FP_NAN) { return x; } else if (yfpclas == FP_NAN) { union _ieee_double x_val; x_val.dword = _SGL_NaN; return(x_val.dword); } else if (xfpclas == FP_ZERO && yfpclas == FP_ZERO) { return x; } else if (xfpclas == FP_INFINITE) { return x; } else if ((long double) x == y) { return x; } else if (xfpclas == FP_ZERO) { union _ieee_double x_val; x_val.dword = DBL_MIN; x_val.parts.sign = (long double) x > y; /* return smallest normal number */ return(x_val.dword); } else { /* first argument is normal or denormal */ union _ieee_double x_val; int j; int resfpclas; x_val.dword = x; /* move one bit in the correct direction. ** Because of the way the implicit bit works, ** the exponent field is handled correctly. */ if (x > 0) { x_val.lword += ((long double) x > y) ? -1 : 1; } else { x_val.lword += ((long double) x > y) ? 1 : -1; } /* test for underflow or overflow */ if (_isnormal(x_val.dword)) return(x_val.dword); /* * Raise overflow exception for infinite result and * underflow exception for too small result. Raise * inexact exception for both cases. Allow subnormal * values to return without exception. */ resfpclas = _fpclassify(x_val.dword); if (resfpclas == FP_INFINITE) { j = FE_OVERFLOW; feraiseexcept(j); } else if (resfpclas == FP_ZERO) { j = FE_UNDERFLOW; feraiseexcept(j); } else { return(x_val.dword); } j = FE_INEXACT; feraiseexcept(j); return(x_val.dword); } }