summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--neg.c15
-rw-r--r--set_f.c48
-rw-r--r--ui_sub.c25
3 files changed, 52 insertions, 36 deletions
diff --git a/neg.c b/neg.c
index b67e0c9d2..c433a5ee9 100644
--- a/neg.c
+++ b/neg.c
@@ -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;
+ }
}
diff --git a/set_f.c b/set_f.c
index 91bbbcd85..93bfd5501 100644
--- a/set_f.c
+++ b/set_f.c
@@ -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;
}
diff --git a/ui_sub.c b/ui_sub.c
index e08bcf244..e882882e9 100644
--- a/ui_sub.c
+++ b/ui_sub.c
@@ -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 */
}