summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
8c071f8)
this is necessary to support archs where fenv is incomplete or
unavailable (presently arm). fma, fmal, and the lrint family should
work perfectly fine with this change; fmaf is slightly broken with
respect to rounding as it depends on non-default rounding modes to do
its work.
* modes other than FE_TONEAREST are painful.
*/
if (spread < -DBL_MANT_DIG) {
* modes other than FE_TONEAREST are painful.
*/
if (spread < -DBL_MANT_DIG) {
feraiseexcept(FE_INEXACT);
feraiseexcept(FE_INEXACT);
+#endif
+#ifdef FE_UNDERFLOW
if (!isnormal(z))
feraiseexcept(FE_UNDERFLOW);
if (!isnormal(z))
feraiseexcept(FE_UNDERFLOW);
+ default: /* FE_TONEAREST */
case FE_TOWARDZERO:
if (x > 0.0 ^ y < 0.0 ^ z < 0.0)
return (z);
else
return (nextafter(z, 0));
case FE_TOWARDZERO:
if (x > 0.0 ^ y < 0.0 ^ z < 0.0)
return (z);
else
return (nextafter(z, 0));
+#endif
+#ifdef FE_DOWNWARD
case FE_DOWNWARD:
if (x > 0.0 ^ y < 0.0)
return (z);
else
return (nextafter(z, -INFINITY));
case FE_DOWNWARD:
if (x > 0.0 ^ y < 0.0)
return (z);
else
return (nextafter(z, -INFINITY));
- default: /* FE_UPWARD */
+#endif
+#ifdef FE_UPWARD
+ case FE_UPWARD:
if (x > 0.0 ^ y < 0.0)
return (nextafter(z, INFINITY));
else
return (z);
if (x > 0.0 ^ y < 0.0)
return (nextafter(z, INFINITY));
else
return (z);
}
}
if (spread <= DBL_MANT_DIG * 2)
}
}
if (spread <= DBL_MANT_DIG * 2)
* If result is inexact, and exactly halfway between two float values,
* we need to adjust the low-order bit in the direction of the error.
*/
* If result is inexact, and exactly halfway between two float values,
* we need to adjust the low-order bit in the direction of the error.
*/
fesetround(FE_TOWARDZERO);
fesetround(FE_TOWARDZERO);
volatile double vxy = xy; /* XXX work around gcc CSE bug */
double adjusted_result = vxy + z;
fesetround(FE_TONEAREST);
volatile double vxy = xy; /* XXX work around gcc CSE bug */
double adjusted_result = vxy + z;
fesetround(FE_TONEAREST);
* modes other than FE_TONEAREST are painful.
*/
if (spread < -LDBL_MANT_DIG) {
* modes other than FE_TONEAREST are painful.
*/
if (spread < -LDBL_MANT_DIG) {
feraiseexcept(FE_INEXACT);
feraiseexcept(FE_INEXACT);
+#endif
+#ifdef FE_UNDERFLOW
if (!isnormal(z))
feraiseexcept(FE_UNDERFLOW);
if (!isnormal(z))
feraiseexcept(FE_UNDERFLOW);
+ default: /* FE_TONEAREST */
case FE_TOWARDZERO:
if (x > 0.0 ^ y < 0.0 ^ z < 0.0)
return (z);
else
return (nextafterl(z, 0));
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));
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);
if (x > 0.0 ^ y < 0.0)
return (nextafterl(z, INFINITY));
else
return (z);
}
}
if (spread <= LDBL_MANT_DIG * 2)
}
}
if (spread <= LDBL_MANT_DIG * 2)
feholdexcept(&env);
d = (dtype)roundit(x);
feholdexcept(&env);
d = (dtype)roundit(x);
+#if defined(FE_INVALID) && defined(FE_INEXACT)
if (fetestexcept(FE_INVALID))
feclearexcept(FE_INEXACT);
if (fetestexcept(FE_INVALID))
feclearexcept(FE_INEXACT);
feupdateenv(&env);
return d;
}
feupdateenv(&env);
return d;
}