summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/mpfr.texi17
-rw-r--r--src/mpfr-impl.h4
-rw-r--r--src/set_exp.c4
3 files changed, 19 insertions, 6 deletions
diff --git a/doc/mpfr.texi b/doc/mpfr.texi
index 771f16989..dc1b5efc6 100644
--- a/doc/mpfr.texi
+++ b/doc/mpfr.texi
@@ -2835,10 +2835,9 @@ infinity or zero is undefined.
@end deftypefun
@deftypefun int mpfr_set_exp (mpfr_t @var{x}, mpfr_exp_t @var{e})
-Set the exponent of @var{x} if @var{e} is in the current exponent range,
-and return 0 (even if @var{x} is not a non-zero ordinary number);
-otherwise, return a non-zero value.
-The significand is assumed to be in [1/2,1).
+Set the exponent of @var{x} to @var{e} if @var{x} is a non-zero ordinary
+number and @var{e} is in the current exponent range, and return 0;
+otherwise, return a non-zero value (@var{x} is not changed).
@end deftypefun
@deftypefun int mpfr_signbit (mpfr_t @var{op})
@@ -3646,6 +3645,16 @@ Note: this function has been renamed to @code{mpfr_get_z_2exp}
in MPFR 3.0, but @code{mpfr_get_z_exp} is still available for
compatibility reasons.
+@item @code{mpfr_set_exp} changed in MPFR 3.2.
+Before MPFR 3.2, the exponent was set whatever the contents of the MPFR
+object in argument. In practice, this could be useful as a low-level
+function when the MPFR number was being constructed by setting the fields
+of its internal structure, but the API does not provide a way to do this
+except by using internals. Thus, for the API, this behavior was useless
+and could quickly lead to undefined behavior due to the fact that the
+generated value could have an invalid format if the MPFR object contained
+a special value (NaN, infinity or zero).
+
@item @code{mpfr_strtofr} changed in MPFR 2.3.1 and MPFR 2.4.
This was actually a bug fix since the code and the documentation did
not match. But both were changed in order to have a more consistent
diff --git a/src/mpfr-impl.h b/src/mpfr-impl.h
index 569bb8336..eee6afae2 100644
--- a/src/mpfr-impl.h
+++ b/src/mpfr-impl.h
@@ -784,7 +784,9 @@ typedef intmax_t mpfr_eexp_t;
#ifdef MPFR_EXP_CHECK
# define MPFR_GET_EXP(x) (mpfr_get_exp) (x)
-# define MPFR_SET_EXP(x, exp) MPFR_ASSERTN (!mpfr_set_exp ((x), (exp)))
+# define MPFR_SET_EXP(x, exp) (MPFR_ASSERTN ((exp) >= __gmpfr_emin && \
+ (exp) <= __gmpfr_emax), \
+ (void) (MPFR_EXP (x) = (exp)))
# define MPFR_SET_INVALID_EXP(x) ((void) (MPFR_EXP (x) = MPFR_EXP_INVALID))
#else
# define MPFR_GET_EXP(x) MPFR_EXP (x)
diff --git a/src/set_exp.c b/src/set_exp.c
index 22322ea32..42defe268 100644
--- a/src/set_exp.c
+++ b/src/set_exp.c
@@ -25,7 +25,9 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
int
mpfr_set_exp (mpfr_ptr x, mpfr_exp_t exponent)
{
- if (MPFR_LIKELY (exponent >= __gmpfr_emin && exponent <= __gmpfr_emax))
+ if (MPFR_LIKELY (MPFR_IS_PURE_FP (x) &&
+ exponent >= __gmpfr_emin &&
+ exponent <= __gmpfr_emax))
{
MPFR_EXP(x) = exponent; /* do not use MPFR_SET_EXP of course... */
return 0;