From e3dcaaf0d9e206b0acd9597622c6d3d423cb5ed5 Mon Sep 17 00:00:00 2001 From: vlefevre Date: Thu, 26 Mar 2020 17:09:28 +0000 Subject: [src] Portability fixes. Avoid a potential integer overflow with huge precisions. (merged changesets r13792-13793,13795 from the trunk) git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/4.0@13828 280ebfd0-de03-0410-8827-d642c229c3f4 --- src/agm.c | 2 +- src/pow.c | 11 +++++++---- src/rem1.c | 6 ++++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/agm.c b/src/agm.c index faa23d266..4a39c2e44 100644 --- a/src/agm.c +++ b/src/agm.c @@ -220,7 +220,7 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mpfr_rnd_t rnd_mode) mpfr_add (vf, u, v, MPFR_RNDN); /* No overflow? */ mpfr_div_2ui (vf, vf, 1, MPFR_RNDN); /* See proof in algorithms.tex */ - if (4*eq > p) + if (eq > p / 4) { mpfr_t w; MPFR_BLOCK_DECL (flags3); diff --git a/src/pow.c b/src/pow.c index 0063c0041..9fec8025e 100644 --- a/src/pow.c +++ b/src/pow.c @@ -34,8 +34,7 @@ mpfr_pow_is_exact (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode, int *inexact) { mpz_t a, c; - mpfr_exp_t d, b; - unsigned long i; + mpfr_exp_t d, b, i; int res; MPFR_ASSERTD (!MPFR_IS_SINGULAR (y)); @@ -48,7 +47,9 @@ mpfr_pow_is_exact (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, if (MPFR_IS_NEG (y)) return 0; /* x is not a power of two => x^-y is not exact */ - /* compute d such that y = c*2^d with c odd integer */ + /* Compute d such that y = c*2^d with c odd integer. + Since c comes from a regular MPFR number, due to the constraints on the + exponent and the precision, there can be no integer overflow below. */ mpz_init (c); d = mpfr_get_z_2exp (c, y); i = mpz_scan1 (c, 0); @@ -58,7 +59,9 @@ mpfr_pow_is_exact (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, /* Since y is not an integer, d is necessarily < 0 */ MPFR_ASSERTD (d < 0); - /* Compute a,b such that x=a*2^b */ + /* Compute a,b such that x=a*2^b. + Since a comes from a regular MPFR number, due to the constrainst on the + exponent and the precision, there can be no integer overflow below. */ mpz_init (a); b = mpfr_get_z_2exp (a, x); i = mpz_scan1 (a, 0); diff --git a/src/rem1.c b/src/rem1.c index 3a7173c24..0ac742749 100644 --- a/src/rem1.c +++ b/src/rem1.c @@ -100,9 +100,11 @@ mpfr_rem1 (mpfr_ptr rem, long *quo, mpfr_rnd_t rnd_q, mpz_abs (my, my); q_is_odd = 0; - /* divide my by 2^k if possible to make operations mod my easier */ + /* Divide my by 2^k if possible to make operations mod my easier. + Since my comes from a regular MPFR number, due to the constraints on the + exponent and the precision, there can be no integer overflow below. */ { - unsigned long k = mpz_scan1 (my, 0); + mpfr_exp_t k = mpz_scan1 (my, 0); ey += k; mpz_fdiv_q_2exp (my, my, k); } -- cgit v1.2.1