EXPORT_C int __isnanl(long double e) { union IEEEl2bits u; u.e = e; mask_nbit_l(u); return (u.bits.exp == 32767 && (u.bits.manl != 0 || u.bits.manh != 0)); }
DLLEXPORT int __isinfl(long double e) { union IEEEl2bits u; u.e = e; mask_nbit_l(u); return (u.bits.exp == 32767 && u.bits.manl == 0 && u.bits.manh == 0); }
DLLEXPORT long double fmaxl(long double x, long double y) { union IEEEl2bits u[2]; u[0].e = x; mask_nbit_l(u[0]); u[1].e = y; mask_nbit_l(u[1]); /* Check for NaNs to avoid raising spurious exceptions. */ if (u[0].bits.exp == 32767 && (u[0].bits.manh | u[0].bits.manl) != 0) return (y); if (u[1].bits.exp == 32767 && (u[1].bits.manh | u[1].bits.manl) != 0) return (x); /* Handle comparisons of signed zeroes. */ if (u[0].bits.sign != u[1].bits.sign) return (u[0].bits.sign ? y : x); return (x > y ? x : y); }
int __isinfl(long double e) { union IEEEl2bits u; u.e = e; mask_nbit_l(u); #ifndef __alpha__ return (u.bits.exp == 32767 && u.bits.manl == 0 && u.bits.manh == 0); #else return (u.bits.exp == 2047 && u.bits.manl == 0 && u.bits.manh == 0); #endif }
long double nextafterl(long double x, long double y) { volatile long double t; union IEEEl2bits ux, uy; ux.e = x; uy.e = y; if ((ux.bits.exp == 0x7fff && ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl) != 0) || (uy.bits.exp == 0x7fff && ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0)) return x+y; /* x or y is nan */ if(x==y) return y; /* x=y, return y */ if(x==0.0) { ux.bits.manh = 0; /* return +-minsubnormal */ ux.bits.manl = 1; ux.bits.sign = uy.bits.sign; t = ux.e*ux.e; if(t==ux.e) return t; else return ux.e; /* raise underflow flag */ } //asq: XXX: original was: if(x>0.0 ^ x<y) if((x>0.0) ^ (x<y)) { /* x -= ulp */ if(ux.bits.manl==0) { if ((ux.bits.manh&~LDBL_NBIT)==0) ux.bits.exp -= 1; ux.bits.manh = (ux.bits.manh - 1) | (ux.bits.manh & LDBL_NBIT); } ux.bits.manl -= 1; } else { /* x += ulp */ ux.bits.manl += 1; if(ux.bits.manl==0) { ux.bits.manh = (ux.bits.manh + 1) | (ux.bits.manh & LDBL_NBIT); if ((ux.bits.manh&~LDBL_NBIT)==0) ux.bits.exp += 1; } } if(ux.bits.exp==0x7fff) return x+x; /* overflow */ if(ux.bits.exp==0) { /* underflow */ mask_nbit_l(ux); t = ux.e * ux.e; if(t!=ux.e) /* raise underflow flag */ return ux.e; } return ux.e; }
EXPORT_C int __fpclassifyl(long double e) { union IEEEl2bits u; u.e = e; if (u.bits.exp == 0) { if ((u.bits.manl | u.bits.manh) == 0) return (FP_ZERO); return (FP_SUBNORMAL); } mask_nbit_l(u); /* Mask normalization bit if applicable. */ if (u.bits.exp == 32767) { if ((u.bits.manl | u.bits.manh) == 0) return (FP_INFINITE); return (FP_NAN); } return (FP_NORMAL); }
/* * IEEE functions * nextafterl(x,y) * return the next machine floating-point number of x in the * direction toward y. * Special cases: * If x == y, y shall be returned * If x or y is NaN, a NaN shall be returned */ long double nextafterl(long double x, long double y) { volatile long double t; union ieee_ext_u ux, uy; ux.extu_ld = x; uy.extu_ld = y; if ((ux.extu_exp == EXT_EXP_NAN && ((ux.extu_frach &~ LDBL_NBIT)|ux.extu_fracl) != 0) || (uy.extu_exp == EXT_EXP_NAN && ((uy.extu_frach &~ LDBL_NBIT)|uy.extu_fracl) != 0)) return x+y; /* x or y is nan */ if (x == y) return y; /* x=y, return y */ if (x == 0.0) { ux.extu_frach = 0; /* return +-minsubnormal */ ux.extu_fracl = 1; ux.extu_sign = uy.extu_sign; t = ux.extu_ld * ux.extu_ld; if (t == ux.extu_ld) return t; else return ux.extu_ld; /* raise underflow flag */ } if ((x>0.0) ^ (x<y)) { /* x -= ulp */ if (ux.extu_fracl == 0) { if ((ux.extu_frach & ~LDBL_NBIT) == 0) ux.extu_exp -= 1; ux.extu_frach = (ux.extu_frach - 1) | (ux.extu_frach & LDBL_NBIT); } ux.extu_fracl -= 1; } else { /* x += ulp */ ux.extu_fracl += 1; if (ux.extu_fracl == 0) { ux.extu_frach = (ux.extu_frach + 1) | (ux.extu_frach & LDBL_NBIT); if ((ux.extu_frach & ~LDBL_NBIT) == 0) ux.extu_exp += 1; } } if (ux.extu_exp == EXT_EXP_INF) return x+x; /* overflow */ if (ux.extu_exp == 0) { /* underflow */ mask_nbit_l(ux); t = ux.extu_ld * ux.extu_ld; if (t != ux.extu_ld) /* raise underflow flag */ return ux.extu_ld; } return ux.extu_ld; }