diff options
-rw-r--r-- | neg.c | 15 | ||||
-rw-r--r-- | set_f.c | 48 | ||||
-rw-r--r-- | ui_sub.c | 25 |
3 files changed, 52 insertions, 36 deletions
@@ -1,8 +1,9 @@ /* mpfr_neg -- change the sign of a floating-point number -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999-2001 Free Software Foundation. This file is part of the MPFR Library. +Contributed by the Spaces project (LORIA/LIP6). The MPFR Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by @@ -24,7 +25,7 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "mpfr-impl.h" -void +int #if __STDC__ mpfr_neg (mpfr_ptr a, mpfr_srcptr b, mp_rnd_t rnd_mode) #else @@ -34,7 +35,11 @@ mpfr_neg (a, b, rnd_mode) mp_rnd_t rnd_mode; #endif { - if (a != b) mpfr_set4(a, b, rnd_mode, -MPFR_SIGN(b)); - else MPFR_CHANGE_SIGN(a); - return; + if (a != b) + return mpfr_set4 (a, b, rnd_mode, -MPFR_SIGN(b)); + else + { + MPFR_CHANGE_SIGN(a); + return 0; + } } @@ -26,7 +26,7 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "mpfr-impl.h" -void +int #if __STDC__ mpfr_set_f(mpfr_ptr y, mpf_srcptr x, mp_rnd_t rnd_mode) #else @@ -36,41 +36,55 @@ mpfr_set_f(y, x, rnd_mode) mp_rnd_t rnd_mode; #endif { - mp_limb_t *my, *mx, *tmp; unsigned long cnt, sx, sy; + mp_limb_t *my, *mx, *tmp; + unsigned long cnt, sx, sy; + int inexact; TMP_DECL(marker); - if (SIZ(x) * MPFR_SIGN(y) < 0) MPFR_CHANGE_SIGN(y); + if (SIZ(x) * MPFR_SIGN(y) < 0) + MPFR_CHANGE_SIGN (y); - MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS (y); - TMP_MARK(marker); - sx = ABS(SIZ(x)); sy = MPFR_ABSSIZE(y); - my = MPFR_MANT(y); mx = PTR(x); + sx = ABS(SIZ(x)); /* number of limbs of the mantissa of x */ + sy = 1 + (MPFR_PREC(y) - 1) / BITS_PER_MP_LIMB; + my = MPFR_MANT(y); + mx = PTR(x); - if (sx==0) { /* x is zero */ - MPFR_SET_ZERO(y); return; - } + if (sx == 0) /* x is zero */ + { + MPFR_SET_ZERO(y); + return 0; /* 0 is exact */ + } count_leading_zeros(cnt, mx[sx - 1]); - if (sy < sx) + if (sy <= sx) /* we may have to round even when sy = sx */ { unsigned long xprec = sx * BITS_PER_MP_LIMB; + TMP_MARK(marker); tmp = (mp_limb_t*) TMP_ALLOC(xprec); - if (cnt) mpn_lshift(tmp, mx, sx, cnt); - else MPN_COPY(tmp, mx, sx); - mpfr_round_raw(my, tmp, xprec, (SIZ(x)<0), MPFR_PREC(y), rnd_mode, NULL); + if (cnt) + mpn_lshift(tmp, mx, sx, cnt); + else + MPN_COPY(tmp, mx, sx); + mpfr_round_raw (my, tmp, xprec, (SIZ(x)<0), MPFR_PREC(y), rnd_mode, + &inexact); + TMP_FREE(marker); } else { - if (cnt) mpn_lshift(my + sy - sx, mx, sx, cnt); - else MPN_COPY(my + sy - sx, mx, sy); + if (cnt) + mpn_lshift(my + sy - sx, mx, sx, cnt); + else + MPN_COPY(my + sy - sx, mx, sy); MPN_ZERO(my, sy - sx); /* no rounding necessary, since y has a larger mantissa */ + inexact = 0; } MPFR_EXP(y) = EXP(x) * BITS_PER_MP_LIMB - cnt; - TMP_FREE(marker); + return inexact; } @@ -26,7 +26,7 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "mpfr-impl.h" -void +int #if __STDC__ mpfr_ui_sub (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mp_rnd_t rnd_mode) #else @@ -40,13 +40,11 @@ mpfr_ui_sub (y, u, x, rnd_mode) mpfr_t uu; mp_limb_t up[1]; unsigned long cnt; - - if (MPFR_IS_NAN(x)) { MPFR_SET_NAN(y); - return; + return 1; /* a NaN is inexact */ } MPFR_CLEAR_NAN(y); @@ -54,20 +52,19 @@ mpfr_ui_sub (y, u, x, rnd_mode) if (MPFR_IS_INF(x)) { MPFR_SET_INF(y); - if (MPFR_SIGN(x) == MPFR_SIGN(y)) MPFR_CHANGE_SIGN(y); - return; + if (MPFR_SIGN(x) == MPFR_SIGN(y)) + MPFR_CHANGE_SIGN(y); + return 0; /* +/-infinity is exact */ } if (u) { - - - MPFR_INIT1(up, uu, BITS_PER_MP_LIMB, 1); - count_leading_zeros(cnt, (mp_limb_t) u); + MPFR_INIT1 (up, uu, BITS_PER_MP_LIMB, 1); + count_leading_zeros (cnt, (mp_limb_t) u); *up = (mp_limb_t) u << cnt; - MPFR_EXP(uu) = BITS_PER_MP_LIMB-cnt; + MPFR_EXP(uu) = BITS_PER_MP_LIMB - cnt; - mpfr_sub (y, uu, x, rnd_mode); - + return mpfr_sub (y, uu, x, rnd_mode); } - else mpfr_neg (y, x, rnd_mode); /* if u=0, then set y to -x */ + else + return mpfr_neg (y, x, rnd_mode); /* if u=0, then set y to -x */ } |