summaryrefslogtreecommitdiff
path: root/sysdeps/ieee754/flt-32/e_jnf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/ieee754/flt-32/e_jnf.c')
-rw-r--r--sysdeps/ieee754/flt-32/e_jnf.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/sysdeps/ieee754/flt-32/e_jnf.c b/sysdeps/ieee754/flt-32/e_jnf.c
index 5984d94a3c..44a3761adb 100644
--- a/sysdeps/ieee754/flt-32/e_jnf.c
+++ b/sysdeps/ieee754/flt-32/e_jnf.c
@@ -14,6 +14,7 @@
*/
#include <errno.h>
+#include <float.h>
#include <math.h>
#include <math_private.h>
@@ -26,6 +27,8 @@ static const float zero = 0.0000000000e+00;
float
__ieee754_jnf(int n, float x)
{
+ float ret;
+ {
int32_t i,hx,ix, sgn;
float a, b, temp, di;
float z, w;
@@ -46,8 +49,9 @@ __ieee754_jnf(int n, float x)
if(n==1) return(__ieee754_j1f(x));
sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */
x = fabsf(x);
+ SET_RESTORE_ROUNDF (FE_TONEAREST);
if(__builtin_expect(ix==0||ix>=0x7f800000, 0)) /* if x is 0 or inf */
- b = zero;
+ return sgn == 1 ? -zero : zero;
else if((float)n<=x) {
/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
a = __ieee754_j0f(x);
@@ -162,13 +166,23 @@ __ieee754_jnf(int n, float x)
b = (t * w / a);
}
}
- if(sgn==1) return -b; else return b;
+ if(sgn==1) ret = -b; else ret = b;
+ }
+ if (ret == 0)
+ ret = __copysignf (FLT_MIN, ret) * FLT_MIN;
+ else if (fabsf (ret) < FLT_MIN) {
+ float force_underflow = ret * ret;
+ math_force_eval (force_underflow);
+ }
+ return ret;
}
strong_alias (__ieee754_jnf, __jnf_finite)
float
__ieee754_ynf(int n, float x)
{
+ float ret;
+ {
int32_t i,hx,ix;
u_int32_t ib;
int32_t sign;
@@ -187,7 +201,11 @@ __ieee754_ynf(int n, float x)
sign = 1 - ((n&1)<<1);
}
if(n==0) return(__ieee754_y0f(x));
- if(n==1) return(sign*__ieee754_y1f(x));
+ SET_RESTORE_ROUNDF (FE_TONEAREST);
+ if(n==1) {
+ ret = sign*__ieee754_y1f(x);
+ goto out;
+ }
if(__builtin_expect(ix==0x7f800000, 0)) return zero;
a = __ieee754_y0f(x);
@@ -201,8 +219,13 @@ __ieee754_ynf(int n, float x)
a = temp;
}
/* If B is +-Inf, set up errno accordingly. */
- if (! __finitef (b))
+ if (! isfinite (b))
__set_errno (ERANGE);
- if(sign>0) return b; else return -b;
+ if(sign>0) ret = b; else ret = -b;
+ }
+ out:
+ if (isinf (ret))
+ ret = __copysignf (FLT_MAX, ret) * FLT_MAX;
+ return ret;
}
strong_alias (__ieee754_ynf, __ynf_finite)