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)); }
double _IEEE_REMAINDER_H_R(float argx, double argy) { union _ieee_double { double dword; long lword; }; double __remainder_r(double x, double y); double x_val; int xfpclas = _fpclassifyf(argx); int yfpclas = _fpclassify(argy); if ((xfpclas == FP_INFINITE) || yfpclas == FP_ZERO) { union _ieee_double x_val; int j; x_val.dword = _SGL_NaN; /* need to emit invalid exception */ j = FE_INVALID; feraiseexcept(j); return(x_val.dword); } x_val = (double) argx; return(__remainder_r(x_val, argy)); }
double _IEEE_BINARY_SCALE_I4(double x, short n) { /* Union defined to work with IEEE 64-bit floating point. */ union _ieee_double { double dword; long lword; unsigned ulword; struct { unsigned int sign : 1; unsigned int exponent : IEEE_64_EXPO_BITS; unsigned int mantissa : IEEE_64_MANT_BITS; } parts; }; int fp_class = _fpclassify(x); if (fp_class==FP_NORMAL) { union _ieee_double x_val; long exponent; x_val.dword = x; exponent = x_val.parts.exponent + (int) n; if (exponent <= 0) { int j; long full_mantissa = x_val.parts.mantissa; /* need to emit underflow exception */ j = FE_UNDERFLOW; feraiseexcept(j); /* add implicit bit to mantissa */ full_mantissa |= IEEE_64_IMPLICIT_BIT; /* shift mantissa over by exponent remaining */ full_mantissa >>= -exponent + 1; /* return denormal number */ x_val.parts.exponent = 0; x_val.parts.mantissa = full_mantissa; } else if ((exponent>>IEEE_64_EXPO_BITS) != 0) {
double _IEEE_NEXT_AFTER_R_R(double x, double y) { /* Union defined to work with IEEE 64-bit floating point. */ union _ieee_double { double dword; long long lword; struct { #if defined(_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 = _fpclassify(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_double x_val; x_val.dword = DBL_MIN; x_val.parts.sign = 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 += (x>y) ? -1 : 1; } else { x_val.lword += (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); } }
float _IEEE_EXPONENT_H_R(double x) { /* Union defined to work with IEEE 32 bit floating point. */ union _ieee_float { float dword; int lword; struct { #if defined(_LITTLE_ENDIAN) unsigned int mantissa : IEEE_32_MANT_BITS; unsigned int exponent : IEEE_32_EXPO_BITS; unsigned int sign : 1; #else unsigned int sign : 1; unsigned int exponent : IEEE_32_EXPO_BITS; unsigned int mantissa : IEEE_32_MANT_BITS; #endif } fparts; }; union _ieee_double { double dwrd; long long lwrd; struct { #if defined(_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 (_fpclassify(x)) { case FP_NAN: { union _ieee_float x_val; x_val.lword = _HALF_NaN; return(x_val.dword); } case FP_INFINITE: { union _ieee_float x_val; x_val.lword = IEEE_32_INFINITY; return(x_val.dword); } case FP_NORMAL: { union _ieee_double x_val; x_val.dwrd = x; return(x_val.parts.expon - IEEE_64_EXPO_BIAS); } case FP_SUBNORMAL: { union _ieee_double x_val; int y; x_val.dwrd = x; /* _leadz returns number of zeros before first 1 * in mantissa. Add IEEE_64_EXPO_BITS to exclude * exponent bits, but count sign bit since * implicit bit needs to be counted. */ return(-IEEE_64_EXPO_BIAS - _leadz(x_val.parts.mantissa) + IEEE_64_EXPO_BITS); } case FP_ZERO: { int j; union _ieee_float x_val; /* raise divide-by-zero exception */ j = FE_DIVBYZERO; feraiseexcept(j); /* return negative infinity */ x_val.lword = IEEE_32_INFINITY; x_val.fparts.sign = 1; return(x_val.dword); } } }