diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/math/fma.c | 14 | ||||
| -rw-r--r-- | src/math/fmaf.c | 2 | ||||
| -rw-r--r-- | src/math/fmal.c | 14 | ||||
| -rw-r--r-- | src/math/lrint.c | 2 | 
4 files changed, 28 insertions, 4 deletions
| diff --git a/src/math/fma.c b/src/math/fma.c index c53f3148..f44ecda7 100644 --- a/src/math/fma.c +++ b/src/math/fma.c @@ -199,27 +199,37 @@ double fma(double x, double y, double z)  	 * modes other than FE_TONEAREST are painful.  	 */  	if (spread < -DBL_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 (nextafter(z, 0)); +#endif +#ifdef FE_DOWNWARD  		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); +#endif  		}  	}  	if (spread <= DBL_MANT_DIG * 2) diff --git a/src/math/fmaf.c b/src/math/fmaf.c index 0dccf108..cc427fb5 100644 --- a/src/math/fmaf.c +++ b/src/math/fmaf.c @@ -54,7 +54,9 @@ float fmaf(float x, float y, float z)  	 * 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.  	 */ +#ifdef FE_TOWARDZERO  	fesetround(FE_TOWARDZERO); +#endif  	volatile double vxy = xy;  /* XXX work around gcc CSE bug */  	double adjusted_result = vxy + z;  	fesetround(FE_TONEAREST); diff --git a/src/math/fmal.c b/src/math/fmal.c index 200bd5a5..3944c292 100644 --- a/src/math/fmal.c +++ b/src/math/fmal.c @@ -194,27 +194,37 @@ long double fmal(long double x, long double y, long double z)  	 * 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) diff --git a/src/math/lrint.c b/src/math/lrint.c index 98d58ad0..9754fa74 100644 --- a/src/math/lrint.c +++ b/src/math/lrint.c @@ -49,8 +49,10 @@ dtype fn(type x)  	feholdexcept(&env);  	d = (dtype)roundit(x); +#if defined(FE_INVALID) && defined(FE_INEXACT)  	if (fetestexcept(FE_INVALID))  		feclearexcept(FE_INEXACT); +#endif  	feupdateenv(&env);  	return d;  } | 
