diff options
author | zimmerma <zimmerma@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2012-06-28 06:14:31 +0000 |
---|---|---|
committer | zimmerma <zimmerma@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2012-06-28 06:14:31 +0000 |
commit | f8b2ea0b846dbf6eb794cca8875b5a60446cec18 (patch) | |
tree | 6970181ddeb88c71fb0f788c2df8eb07caf1b2c8 /src | |
parent | def726e7ea3e72d6ae2c30d1247db557d768cacd (diff) | |
download | mpc-f8b2ea0b846dbf6eb794cca8875b5a60446cec18.tar.gz |
increase code coverage to 99.9%
git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@1199 211d60ee-9f03-0410-a15a-8952a2c7a4e4
Diffstat (limited to 'src')
-rw-r--r-- | src/div.c | 54 | ||||
-rw-r--r-- | src/log10.c | 34 | ||||
-rw-r--r-- | src/pow.c | 9 | ||||
-rw-r--r-- | src/sqrt.c | 26 |
4 files changed, 63 insertions, 60 deletions
@@ -312,45 +312,53 @@ mpc_div (mpc_ptr a, mpc_srcptr b, mpc_srcptr c, mpc_rnd_t rnd) hopefully, the side-effects of mpc_mul do indeed raise the mpfr exceptions */ if (overflow_prod) { + int isinf = 0; tmpsgn = mpfr_sgn (mpc_realref(res)); if (tmpsgn > 0) - mpfr_nextabove (mpc_realref(res)); + { + mpfr_nextabove (mpc_realref(res)); + isinf = mpfr_inf_p (mpc_realref(res)); + mpfr_nextbelow (mpc_realref(res)); + } else if (tmpsgn < 0) - mpfr_nextbelow (mpc_realref(res)); - if (mpfr_inf_p (mpc_realref(res))) + { + mpfr_nextbelow (mpc_realref(res)); + isinf = mpfr_inf_p (mpc_realref(res)); + mpfr_nextabove (mpc_realref(res)); + } + if (isinf) { mpfr_set_inf (mpc_realref(res), tmpsgn); overflow_re = 1; } - else - if (tmpsgn > 0) - mpfr_nextbelow (mpc_realref(res)); - else if (tmpsgn < 0) - mpfr_nextabove (mpc_realref(res)); tmpsgn = mpfr_sgn (mpc_imagref(res)); + isinf = 0; if (tmpsgn > 0) - mpfr_nextabove (mpc_imagref(res)); + { + mpfr_nextabove (mpc_imagref(res)); + isinf = mpfr_inf_p (mpc_imagref(res)); + mpfr_nextbelow (mpc_imagref(res)); + } else if (tmpsgn < 0) - mpfr_nextbelow (mpc_imagref(res)); - if (mpfr_inf_p (mpc_imagref(res))) + { + mpfr_nextbelow (mpc_imagref(res)); + isinf = mpfr_inf_p (mpc_imagref(res)); + mpfr_nextabove (mpc_imagref(res)); + } + if (isinf) { mpfr_set_inf (mpc_imagref(res), tmpsgn); overflow_im = 1; } - else - if (tmpsgn > 0) - mpfr_nextbelow (mpc_imagref(res)); - else if (tmpsgn < 0) - mpfr_nextabove (mpc_imagref(res)); mpc_set (a, res, rnd); goto end; } /* divide the product by the norm */ if (inexact_norm == 0 && (inexact_re == 0 || inexact_im == 0)) { - /* The division has good chances to be exact in at least one part. */ - /* Since this can cause problems when not rounding to the nearest, */ - /* we use the division code of mpfr, which handles the situation. */ + /* The division has good chances to be exact in at least one part. */ + /* Since this can cause problems when not rounding to the nearest, */ + /* we use the division code of mpfr, which handles the situation. */ mpfr_clear_underflow (); mpfr_clear_overflow (); inexact_re |= mpfr_div (mpc_realref (res), mpc_realref (res), q, GMP_RNDZ); @@ -416,16 +424,16 @@ mpc_div (mpc_ptr a, mpc_srcptr b, mpc_srcptr c, mpc_rnd_t rnd) inexact_re = mpfr_sgn (mpc_realref (res)); } else if (underflow_re || (overflow_norm && !overflow_prod)) { - mpfr_set_zero (mpc_realref (a), mpfr_sgn (mpc_realref (res))); - inexact_re = -mpfr_sgn (mpc_realref (res)); + inexact_re = mpfr_signbit (mpc_realref (res)) ? 1 : -1; + mpfr_set_zero (mpc_realref (a), -inexact_re); } if (overflow_im || (underflow_norm && !underflow_prod)) { mpfr_set_inf (mpc_imagref (a), mpfr_sgn (mpc_imagref (res))); inexact_im = mpfr_sgn (mpc_imagref (res)); } else if (underflow_im || (overflow_norm && !overflow_prod)) { - mpfr_set_zero (mpc_imagref (a), mpfr_sgn (mpc_imagref (res))); - inexact_im = -mpfr_sgn (mpc_imagref (res)); + inexact_im = mpfr_signbit (mpc_imagref (res)) ? 1 : -1; + mpfr_set_zero (mpc_imagref (a), -inexact_im); } mpc_clear (res); diff --git a/src/log10.c b/src/log10.c index e5972cc..10a2566 100644 --- a/src/log10.c +++ b/src/log10.c @@ -254,7 +254,7 @@ mpc_log10 (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) mpfr_integer_p (mpc_imagref (op))) { mpz_t x, y; - unsigned long s; + unsigned long s, v; mpz_init (x); mpz_init (y); @@ -263,23 +263,23 @@ mpc_log10 (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) mpz_mul (x, x, x); mpz_mul (y, y, y); mpz_add (x, x, y); /* x^2+y^2 */ - s = mpz_sizeinbase (x, 10); /* always exact or 1 too big */ - /* since s is the number of digits of x in base 10 (or one more), - we subtract 1 since we want to check whether x = 10^s */ - s --; - mpz_ui_pow_ui (y, 10, s); - if (mpz_cmp (y, x) > 0) /* might be 1 too big */ + v = mpz_scan1 (x, 0); + /* if x = 10^s then necessarily s = v */ + s = mpz_sizeinbase (x, 10); + /* since s is either the number of digits of x or one more, + then x = 10^(s-1) or 10^(s-2) */ + if (s == v + 1 || s == v + 2) { - mpz_divexact_ui (y, y, 10); - s --; - } - if (mpz_cmp (y, x) == 0) /* Re(log10(x+i*y)) is exactly s/2 */ - { - /* we reset the precision of Re(ww) so that s can be - represented exactly */ - mpfr_set_prec (mpc_realref (ww), sizeof(unsigned long)*CHAR_BIT); - mpfr_set_ui_2exp (mpc_realref (ww), s, -1, GMP_RNDN); /* exact */ - ok = 1; + mpz_div_2exp (x, x, v); + mpz_ui_pow_ui (y, 5, v); + if (mpz_cmp (y, x) == 0) /* Re(log10(x+i*y)) is exactly v/2 */ + { + /* we reset the precision of Re(ww) so that v can be + represented exactly */ + mpfr_set_prec (mpc_realref (ww), sizeof(unsigned long)*CHAR_BIT); + mpfr_set_ui_2exp (mpc_realref (ww), v, -1, GMP_RNDN); /* exact */ + ok = 1; + } } mpz_clear (x); mpz_clear (y); @@ -202,7 +202,7 @@ mpc_pow_exact (mpc_ptr z, mpc_srcptr x, mpfr_srcptr y, mpc_rnd_t rnd, t = mpz_scan1 (my, 0); ey += (mpfr_exp_t) t; mpz_tdiv_q_2exp (my, my, t); - /* y = my*2^ey */ + /* y = my*2^ey with my odd */ if (x_imag) { @@ -229,7 +229,6 @@ mpc_pow_exact (mpc_ptr z, mpc_srcptr x, mpfr_srcptr y, mpc_rnd_t rnd, mpz_mul_2exp (d, d, (unsigned long int) (ed - ec)); if ((mpfr_prec_t) mpz_sizeinbase (d, 2) > maxprec) goto end; - ed = ec; } else if (ed < ec) { @@ -484,7 +483,7 @@ mpc_pow (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd) mpc_t t, u; mpfr_prec_t p, pr, pi, maxprec; int saved_underflow, saved_overflow; - + /* save the underflow or overflow flags from MPFR */ saved_underflow = mpfr_underflow_p (); saved_overflow = mpfr_overflow_p (); @@ -614,8 +613,8 @@ mpc_pow (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd) (a) x is negative and y is half-an-integer (b) x = -1 and Re(y) is half-an-integer */ - if (mpfr_cmp_ui (mpc_realref(x), 0) < 0 && is_odd (mpc_realref(y), 1) && - (y_real || mpfr_cmp_si (mpc_realref(x), -1) == 0)) + if ((mpfr_cmp_ui (mpc_realref(x), 0) < 0) && is_odd (mpc_realref(y), 1) + && (y_real || mpfr_cmp_si (mpc_realref(x), -1) == 0)) z_imag = 1; } else /* x non real */ @@ -1,6 +1,6 @@ /* mpc_sqrt -- Take the square root of a complex number. -Copyright (C) 2002, 2008, 2009, 2010, 2011 INRIA +Copyright (C) 2002, 2008, 2009, 2010, 2011, 2012 INRIA This file is part of GNU MPC. @@ -329,11 +329,11 @@ mpc_sqrt (mpc_ptr a, mpc_srcptr b, mpc_rnd_t rnd) inex_im = inex_t; else { inex_im = -inex_t; - if ( (im_cmp > 0 && r == GMP_RNDD) - || (im_cmp < 0 && r == GMP_RNDU)) - MPFR_ADD_ONE_ULP (mpc_imagref (a)); - else - MPFR_SUB_ONE_ULP (mpc_imagref (a)); + /* im_cmp > 0 implies that Im(b) > 0, thus im_sgn = 0 + and r = GMP_RNDU. + im_cmp < 0 implies that Im(b) < 0, thus im_sgn = -1 + and r = GMP_RNDD. */ + MPFR_SUB_ONE_ULP (mpc_imagref (a)); } } else if (im_cmp > 0) { @@ -341,21 +341,17 @@ mpc_sqrt (mpc_ptr a, mpc_srcptr b, mpc_rnd_t rnd) inex_re = inex_t; else { inex_re = -inex_t; - if (r == GMP_RNDD) - MPFR_ADD_ONE_ULP (mpc_realref (a)); - else - MPFR_SUB_ONE_ULP (mpc_realref (a)); + /* im_cmp > 0 implies r = GMP_RNDU (see above) */ + MPFR_SUB_ONE_ULP (mpc_realref (a)); } } - else { + else { /* im_cmp < 0 */ if (rnd_t == r) inex_re = -inex_t; else { inex_re = inex_t; - if (r == GMP_RNDD) - MPFR_SUB_ONE_ULP (mpc_realref (a)); - else - MPFR_ADD_ONE_ULP (mpc_realref (a)); + /* im_cmp < 0 implies r = GMP_RNDD (see above) */ + MPFR_SUB_ONE_ULP (mpc_realref (a)); } } } |