if (bits_lost != 1 ^ (int)(u.bits.manl & 1))
sum.hi = nextafterl(sum.hi, INFINITY * sum.lo);
}
- return (ldexp(sum.hi, scale));
+ return scalbnl(sum.hi, scale);
}
/*
* return values here are crucial in handling special cases involving
* infinities, NaNs, overflows, and signed zeroes correctly.
*/
- if (x == 0.0 || y == 0.0)
- return (x * y + z);
- if (z == 0.0)
- return (x * y);
if (!isfinite(x) || !isfinite(y))
return (x * y + z);
if (!isfinite(z))
return (z);
+ if (x == 0.0 || y == 0.0)
+ return (x * y + z);
+ if (z == 0.0)
+ return (x * y);
xs = frexpl(x, &ex);
ys = frexpl(y, &ey);
* modes other than FE_TONEAREST are painful.
*/
if (spread < -LDBL_MANT_DIG) {
+#ifdef FE_INEXACT
feraiseexcept(FE_INEXACT);
+#endif
+#ifdef FE_UNDERFLOW
if (!isnormal(z))
feraiseexcept(FE_UNDERFLOW);
+#endif
switch (oround) {
- case FE_TONEAREST:
+ default: /* FE_TONEAREST */
return (z);
+#ifdef FE_TOWARDZERO
case FE_TOWARDZERO:
if (x > 0.0 ^ y < 0.0 ^ z < 0.0)
return (z);
else
return (nextafterl(z, 0));
+#endif
+#ifdef FE_DOWNWARD
case FE_DOWNWARD:
if (x > 0.0 ^ y < 0.0)
return (z);
else
return (nextafterl(z, -INFINITY));
- default: /* FE_UPWARD */
+#endif
+#ifdef FE_UPWARD
+ case FE_UPWARD:
if (x > 0.0 ^ y < 0.0)
return (nextafterl(z, INFINITY));
else
return (z);
+#endif
}
}
if (spread <= LDBL_MANT_DIG * 2)
- zs = ldexpl(zs, -spread);
+ zs = scalbnl(zs, -spread);
else
zs = copysignl(LDBL_MIN, zs);
*/
fesetround(oround);
volatile long double vzs = zs; /* XXX gcc CSE bug workaround */
- return (xy.hi + vzs + ldexpl(xy.lo, spread));
+ return xy.hi + vzs + scalbnl(xy.lo, spread);
}
if (oround != FE_TONEAREST) {
*/
fesetround(oround);
adj = r.lo + xy.lo;
- return (ldexpl(r.hi + adj, spread));
+ return scalbnl(r.hi + adj, spread);
}
adj = add_adjusted(r.lo, xy.lo);
if (spread + ilogbl(r.hi) > -16383)
- return (ldexpl(r.hi + adj, spread));
+ return scalbnl(r.hi + adj, spread);
else
- return (add_and_denormalize(r.hi, adj, spread));
+ return add_and_denormalize(r.hi, adj, spread);
}
#endif