X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fmath%2Fgen%2Fmp.c;h=be2ed39d6bc7ca9658e032d2a31d3e8557634354;hb=ae0f0fe09b7fc9d44d072c3fd08372991d852b1d;hp=bebc01946b1dff9d25c9ee4544f2a3beef42ba71;hpb=21dd45c44f745d3b85afab304362d01b3b45a5e4;p=libc-test diff --git a/src/math/gen/mp.c b/src/math/gen/mp.c index bebc019..be2ed39 100644 --- a/src/math/gen/mp.c +++ b/src/math/gen/mp.c @@ -123,7 +123,7 @@ static void genf(struct t *p, mpfr_t my, int t, int r) t = adjust(mr, my, t, r); p->y = mpfr_get_flt(mr, r); - p->e = eflags(isnan(p->x) || isnan(p->x2)); + p->e = eflags(isnan(p->x) || isnan(p->x2) || isnan(p->x3)); i = eulpf(p->y); if (!isfinite(p->y)) { p->dy = 0; @@ -193,7 +193,7 @@ static void gend(struct t *p, mpfr_t my, int t, int r) t = adjust(mr, my, t, r); p->y = mpfr_get_d(mr, r); - p->e = eflags(isnan(p->x) || isnan(p->x2)); + p->e = eflags(isnan(p->x) || isnan(p->x2) || isnan(p->x3)); i = eulp(p->y); if (!isfinite(p->y)) { p->dy = 0; @@ -268,7 +268,7 @@ static void genl(struct t *p, mpfr_t my, int t, int r) t = adjust(mr, my, t, r); p->y = mpfr_get_ld(mr, r); - p->e = eflags(isnan(p->x) || isnan(p->x2)); + p->e = eflags(isnan(p->x) || isnan(p->x2) || isnan(p->x3)); i = eulpl(p->y); if (!isfinite(p->y)) { p->dy = 0; @@ -391,6 +391,8 @@ static int wrap_pow10(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r) return mpfr_ui_pow(my, 10, mx, r); } +int mpadd(struct t *t) { return mpd2(t, mpfr_add); } + int mpacos(struct t *t) { return mpd1(t, mpfr_acos); } int mpacosf(struct t *t) { return mpf1(t, mpfr_acos); } int mpacosl(struct t *t) { return mpl1(t, mpfr_acos); } @@ -482,30 +484,69 @@ int mplogb(struct t *t) { MPFR_DECL_INIT(mx, 53); - mpfr_set_d(mx, t->x, MPFR_RNDN); - t->y = mpfr_get_exp(mx) - 1; t->dy = 0; t->e = 0; + if (t->x == 0) { + t->y = -INFINITY; + t->e |= DIVBYZERO; + return 0; + } + if (isinf(t->x)) { + t->y = INFINITY; + return 0; + } + if (isnan(t->x)) { + t->y = t->x; + return 0; + } + mpfr_set_d(mx, t->x, MPFR_RNDN); + t->y = mpfr_get_exp(mx) - 1; return 0; } int mplogbf(struct t *t) { MPFR_DECL_INIT(mx, 24); - mpfr_set_flt(mx, t->x, MPFR_RNDN); - t->y = mpfr_get_exp(mx) - 1; t->dy = 0; t->e = 0; + if (t->x == 0) { + t->y = -INFINITY; + t->e |= DIVBYZERO; + return 0; + } + if (isinf(t->x)) { + t->y = INFINITY; + return 0; + } + if (isnan(t->x)) { + t->y = t->x; + return 0; + } + mpfr_set_flt(mx, t->x, MPFR_RNDN); + t->y = mpfr_get_exp(mx) - 1; return 0; } int mplogbl(struct t *t) { MPFR_DECL_INIT(mx, 64); - mpfr_set_ld(mx, t->x, MPFR_RNDN); - t->y = mpfr_get_exp(mx) - 1; t->dy = 0; t->e = 0; + if (t->x == 0) { + t->y = -INFINITY; + t->e |= DIVBYZERO; + return 0; + } + if (isinf(t->x)) { + t->y = INFINITY; + return 0; + } + if (isnan(t->x)) { + t->y = t->x; + return 0; + } + mpfr_set_ld(mx, t->x, MPFR_RNDN); + t->y = mpfr_get_exp(mx) - 1; return 0; } int mpnearbyint(struct t *t) { return mpd1(t, wrap_nearbyint) || (t->e&=~INEXACT, 0); } @@ -580,6 +621,7 @@ int mptanl(struct t *t) { return mpl1(t, mpfr_tan); } int mptanh(struct t *t) { return mpd1(t, mpfr_tanh); } int mptanhf(struct t *t) { return mpf1(t, mpfr_tanh); } int mptanhl(struct t *t) { return mpl1(t, mpfr_tanh); } +// TODO: tgamma(2) raises wrong flags int mptgamma(struct t *t) { return mpd1(t, mpfr_gamma); } int mptgammaf(struct t *t) { return mpf1(t, mpfr_gamma); } int mptgammal(struct t *t) { return mpl1(t, mpfr_gamma); } @@ -748,6 +790,8 @@ int mpilogb(struct t *t) mpfr_set_d(mx, t->x, MPFR_RNDN); t->i = mpfr_get_exp(mx) - 1; t->e = 0; + if (isinf(t->x) || isnan(t->x) || t->x == 0) + t->e = INVALID; return 0; } int mpilogbf(struct t *t) @@ -757,6 +801,8 @@ int mpilogbf(struct t *t) mpfr_set_flt(mx, t->x, MPFR_RNDN); t->i = mpfr_get_exp(mx) - 1; t->e = 0; + if (isinf(t->x) || isnan(t->x) || t->x == 0) + t->e = INVALID; return 0; } int mpilogbl(struct t *t) @@ -766,6 +812,8 @@ int mpilogbl(struct t *t) mpfr_set_ld(mx, t->x, MPFR_RNDN); t->i = mpfr_get_exp(mx) - 1; t->e = 0; + if (isinf(t->x) || isnan(t->x) || t->x == 0) + t->e = INVALID; return 0; } @@ -801,7 +849,7 @@ int mpmodf(struct t *t) return r; t->y2 = t->y; t->dy2 = t->dy; - e = t->e; + e = t->e & ~INEXACT; r = mpd1(t, mpfr_frac); t->e |= e; return r; @@ -816,7 +864,7 @@ int mpmodff(struct t *t) return r; t->y2 = t->y; t->dy2 = t->dy; - e = t->e; + e = t->e & ~INEXACT; r = mpf1(t, mpfr_frac); t->e |= e; return r; @@ -831,7 +879,7 @@ int mpmodfl(struct t *t) return r; t->y2 = t->y; t->dy2 = t->dy; - e = t->e; + e = t->e & ~INEXACT; r = mpl1(t, mpfr_frac); t->e |= e; return r;