diff options
author | enge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2005-03-03 16:27:24 +0000 |
---|---|---|
committer | enge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2005-03-03 16:27:24 +0000 |
commit | 32efcab8209b7066c8be7549cb70ea4abc7a88f6 (patch) | |
tree | 088e80aa100d7f666d23e7401400001488cd2eaf | |
parent | b0621c335515e90b2b6ebf50f44e8d699f5c1613 (diff) | |
download | mpc-32efcab8209b7066c8be7549cb70ea4abc7a88f6.tar.gz |
handled the case where real and imaginary part have very different
exponents in mpc_sqr
git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@34 211d60ee-9f03-0410-a15a-8952a2c7a4e4
-rw-r--r-- | sqr.c | 23 |
1 files changed, 22 insertions, 1 deletions
@@ -1,6 +1,6 @@ /* mpc_sqr -- Square a complex number. -Copyright (C) 2002 Free Software Foundation, Inc. +Copyright (C) 2002 Andreas Enge, Paul Zimmermann This file is part of the MPC Library. @@ -55,6 +55,27 @@ mpc_sqr (mpc_ptr a, mpc_srcptr b, mpc_rnd_t rnd) inex_im = mpfr_set_ui (MPC_IM(a), 0, GMP_RNDN); return MPC_INEX(inex_re, inex_im); } + /* If the real and imaginary part of the argument have a very different */ + /* exponent, it is not reasonable to use Karatsuba squaring; compute */ + /* exactly with the standard formulae instead, even if this means an */ + /* additional multiplication. */ + if (SAFE_ABS (mp_exp_t, MPFR_EXP (MPC_RE (b)) - MPFR_EXP (MPC_IM (b))) + > MPC_MAX_PREC (b) / 2) + { + mpfr_init2 (u, 2*MPFR_PREC (MPC_RE (b))); + mpfr_init2 (v, 2*MPFR_PREC (MPC_IM (b))); + + mpfr_sqr (u, MPC_RE (b), GMP_RNDN); + mpfr_sqr (v, MPC_IM (b), GMP_RNDN); /* both are exact */ + inex_im = mpfr_mul (a->im, b->re, b->im, MPC_RND_IM (rnd)); + mpfr_mul_2exp (a->im, a->im, 1, GMP_RNDN); + inex_re = mpfr_sub (a->re, u, v, MPC_RND_RE (rnd)); + + mpfr_clear (u); + mpfr_clear (v); + return MPC_INEX (inex_re, inex_im); + } + mpfr_init (u); mpfr_init (v); |