summaryrefslogtreecommitdiff
path: root/set_q.c
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2002-04-19 16:37:15 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2002-04-19 16:37:15 +0000
commit847174a911cf9e6cd1f5e07f8ca489f5214bc8aa (patch)
treeccbeb9544917fa66fb4a939ceb439787d4f98423 /set_q.c
parent01a47f270cbdb4460adcee4d119bca071917e441 (diff)
downloadmpfr-847174a911cf9e6cd1f5e07f8ca489f5214bc8aa.tar.gz
Exponent range saved/restored. Returns NaN when the numerator
or the denominator is too large for MPFR. git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@1901 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'set_q.c')
-rw-r--r--set_q.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/set_q.c b/set_q.c
index a3c6c6fce..a18821c3f 100644
--- a/set_q.c
+++ b/set_q.c
@@ -33,22 +33,36 @@ mpfr_set_q (mpfr_ptr f, mpq_srcptr q, mp_rnd_t rnd)
mpfr_t n, d;
int inexact;
- MPFR_CLEAR_FLAGS(f);
+ MPFR_CLEAR_FLAGS (f);
num = mpq_numref (q);
if (mpz_cmp_ui (num, 0) == 0)
{
- MPFR_SET_ZERO(f);
- MPFR_SET_POS(f);
- MPFR_RET(0);
+ MPFR_SET_ZERO (f);
+ MPFR_SET_POS (f);
+ MPFR_RET (0);
}
- den = mpq_denref(q);
- mpfr_init2 (n, mpz_sizeinbase(num, 2));
- mpfr_set_z (n, num, GMP_RNDZ); /* result is exact */
+ den = mpq_denref (q);
+ mpfr_save_emin_emax ();
+ mpfr_init2 (n, mpz_sizeinbase (num, 2));
+ if (mpfr_set_z (n, num, GMP_RNDZ)) /* result is exact unless overflow */
+ {
+ mpfr_clear (n);
+ mpfr_restore_emin_emax ();
+ MPFR_SET_NAN (f);
+ MPFR_RET_NAN;
+ }
mpfr_init2 (d, mpz_sizeinbase(den, 2));
- mpfr_set_z (d, den, GMP_RNDZ); /* result is exact */
+ if (mpfr_set_z (d, den, GMP_RNDZ)) /* result is exact unless overflow */
+ {
+ mpfr_clear (d);
+ mpfr_clear (n);
+ mpfr_restore_emin_emax ();
+ MPFR_SET_NAN (f);
+ MPFR_RET_NAN;
+ }
inexact = mpfr_div (f, n, d, rnd);
mpfr_clear (n);
mpfr_clear (d);
- MPFR_RET(inexact);
+ MPFR_RESTORE_RET (inexact, f, rnd);
}