diff options
author | enge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2009-09-07 09:42:26 +0000 |
---|---|---|
committer | enge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2009-09-07 09:42:26 +0000 |
commit | 12dfd6d271e059e2d36686091086a5558119e65d (patch) | |
tree | e3d7676aa3e9ddb692bdc5998a4aa7265ebc8a9e | |
parent | e1491914a2a9c8cf6d80e5a475738629b6dcfd71 (diff) | |
download | mpc-12dfd6d271e059e2d36686091086a5558119e65d.tar.gz |
pow.c: renamed variable to avoid duplicate name
mpc.texi: corrected typo
Makefile.vc: new file by M. Gastineau
mul_ui.c, mul_si.c, mul_2exp.c, div_2exp.c: corrected signs of zeroes
correction for mul_fr, mul_i, mul will follow later
git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@668 211d60ee-9f03-0410-a15a-8952a2c7a4e4
-rw-r--r-- | Makefile.vc | 18 | ||||
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | doc/mpc.texi | 4 | ||||
-rw-r--r-- | src/div_2exp.c | 23 | ||||
-rw-r--r-- | src/mul_2exp.c | 23 | ||||
-rw-r--r-- | src/mul_fr.c | 27 | ||||
-rw-r--r-- | src/mul_i.c | 6 | ||||
-rw-r--r-- | src/mul_si.c | 23 | ||||
-rw-r--r-- | src/mul_ui.c | 23 | ||||
-rw-r--r-- | src/pow.c | 22 |
10 files changed, 106 insertions, 64 deletions
diff --git a/Makefile.vc b/Makefile.vc index 5dfba9e..bd1544d 100644 --- a/Makefile.vc +++ b/Makefile.vc @@ -60,7 +60,7 @@ ENDTESTCOMPILE=/LIBPATH:"$(GMPDIR)\lib" libmpc.lib libmpfr.lib libgmp.lib #generate the CPPLINKOBJECTS : goto src and execute # ls *.c | sed "s/\.c/\.obj/" | awk ' { printf("%s \\\n",$1); } ' #generate the list for tests : goto tests and execute -# ls *.c | sed "s/\.c//" | awk ' { printf("\t$(TESTCOMPILE)%s.c $(MIDTESTCOMPILE)%s.exe $(ENDTESTCOMPILE)\n\tcd $(DIRMPCTESTS) && %s.exe && cd ..\n",$1,$1,$1,$1); } ' +# ls t*.c | sed "s/\.c//" | awk ' { printf("\t$(TESTCOMPILE)%s.c $(MIDTESTCOMPILE)%s.exe $(ENDTESTCOMPILE)\n\tcd $(DIRMPCTESTS) && %s.exe && cd ..\n",$1,$1,$1,$1); } ' LIBRARY = libmpc.dll LIBRARYLIB = libmpc.lib @@ -104,8 +104,6 @@ $(DIRMPC)\norm.obj \ $(DIRMPC)\out_str.obj \ $(DIRMPC)\pow.obj \ $(DIRMPC)\proj.obj \ -$(DIRMPC)\random.obj \ -$(DIRMPC)\random2.obj \ $(DIRMPC)\real.obj \ $(DIRMPC)\set.obj \ $(DIRMPC)\set_prec.obj \ @@ -125,7 +123,7 @@ $(DIRMPC)\tanh.obj \ $(DIRMPC)\uceil_log2.obj \ $(DIRMPC)\ui_div.obj \ $(DIRMPC)\ui_ui_sub.obj \ -$(DIRMPC)\urandom.obj +$(DIRMPC)\urandom.obj @@ -168,8 +166,6 @@ norm.obj \ out_str.obj \ pow.obj \ proj.obj \ -random.obj \ -random2.obj \ real.obj \ set.obj \ set_prec.obj \ @@ -189,7 +185,7 @@ tanh.obj \ uceil_log2.obj \ ui_div.obj \ ui_ui_sub.obj \ -urandom.obj +urandom.obj # # Link target: automatically builds its object dependencies before @@ -235,8 +231,6 @@ test : copy $(GMPDIR)\lib\*gmp*.dll $(DIRMPCTESTS) copy $(MPFRDIR)\lib\*mpfr*.dll $(DIRMPCTESTS) copy $(LIBRARY) $(DIRMPCTESTS) - $(TESTCOMPILE)tset.c $(MIDTESTCOMPILE)tset.exe $(ENDTESTCOMPILE) - cd $(DIRMPCTESTS) && tset.exe && cd .. $(TESTCOMPILE)tabs.c $(MIDTESTCOMPILE)tabs.exe $(ENDTESTCOMPILE) cd $(DIRMPCTESTS) && tabs.exe && cd .. $(TESTCOMPILE)tadd.c $(MIDTESTCOMPILE)tadd.exe $(ENDTESTCOMPILE) @@ -269,10 +263,10 @@ test : cd $(DIRMPCTESTS) && tfr_sub.exe && cd .. $(TESTCOMPILE)tget_version.c $(MIDTESTCOMPILE)tget_version.exe $(ENDTESTCOMPILE) cd $(DIRMPCTESTS) && tget_version.exe && cd .. - $(TESTCOMPILE)tio_str.c $(MIDTESTCOMPILE)tio_str.exe $(ENDTESTCOMPILE) - cd $(DIRMPCTESTS) && tio_str.exe && cd .. $(TESTCOMPILE)timag.c $(MIDTESTCOMPILE)timag.exe $(ENDTESTCOMPILE) cd $(DIRMPCTESTS) && timag.exe && cd .. + $(TESTCOMPILE)tio_str.c $(MIDTESTCOMPILE)tio_str.exe $(ENDTESTCOMPILE) + cd $(DIRMPCTESTS) && tio_str.exe && cd .. $(TESTCOMPILE)tlog.c $(MIDTESTCOMPILE)tlog.exe $(ENDTESTCOMPILE) cd $(DIRMPCTESTS) && tlog.exe && cd .. $(TESTCOMPILE)tmul.c $(MIDTESTCOMPILE)tmul.exe $(ENDTESTCOMPILE) @@ -301,6 +295,8 @@ test : cd $(DIRMPCTESTS) && treal.exe && cd .. $(TESTCOMPILE)treimref.c $(MIDTESTCOMPILE)treimref.exe $(ENDTESTCOMPILE) cd $(DIRMPCTESTS) && treimref.exe && cd .. + $(TESTCOMPILE)tset.c $(MIDTESTCOMPILE)tset.exe $(ENDTESTCOMPILE) + cd $(DIRMPCTESTS) && tset.exe && cd .. $(TESTCOMPILE)tsin.c $(MIDTESTCOMPILE)tsin.exe $(ENDTESTCOMPILE) cd $(DIRMPCTESTS) && tsin.exe && cd .. $(TESTCOMPILE)tsinh.c $(MIDTESTCOMPILE)tsinh.exe $(ENDTESTCOMPILE) @@ -5,6 +5,7 @@ Changes in version 0.7: - norm: infinite loop in case of overflow - ui_div, div, fr_div: handling of division by 0 and infinities following the example code of the C99 standard + - mul_ui, mul_si, mul_2exp, div_2exp: signs of zeroes - compilation with g++ - Makefile.vc updated (thanks to Mickael Gastineau) - Minimal gmp version is 4.2 diff --git a/doc/mpc.texi b/doc/mpc.texi index 12650ea..5a9d512 100644 --- a/doc/mpc.texi +++ b/doc/mpc.texi @@ -628,7 +628,7 @@ Set @var{rop} to Nan+i*NaN. @deftypefun void mpc_swap (mpc_t @var{op1}, mpc_t @var{op2}) Swap the values of @var{op1} and @var{op2} efficiently. Warning: the -precisions are exchanged too; in case the precisions are different, +precisions are exchanged too; in case the precisions are different, @code{mpc_swap} is thus not equivalent to three @code{mpc_set} calls using a third auxiliary variable. @end deftypefun @@ -1058,7 +1058,7 @@ Value}). For instance, you can define mpc_set_ui_fr as follows: @example -int mpc_set_ui_d (mpc_t rop, long int re, double im, mpc_rnd_t rnd) +int mpc_set_ui_fr (mpc_t rop, long int re, double im, mpc_rnd_t rnd) MPC_SET_X_Y (ui, fr, rop, re, im, rnd); @end example @end defmac diff --git a/src/div_2exp.c b/src/div_2exp.c index 9459499..7564d74 100644 --- a/src/div_2exp.c +++ b/src/div_2exp.c @@ -24,10 +24,21 @@ MA 02111-1307, USA. */ int mpc_div_2exp (mpc_ptr a, mpc_srcptr b, unsigned long int c, mpc_rnd_t rnd) { - int inex_re, inex_im; - - inex_re = mpfr_div_2exp (MPC_RE(a), MPC_RE(b), c, MPC_RND_RE(rnd)); - inex_im = mpfr_div_2exp (MPC_IM(a), MPC_IM(b), c, MPC_RND_IM(rnd)); - - return MPC_INEX(inex_re, inex_im); + int inex_re, inex_im, inex; + + if (mpfr_cmp_ui (MPC_RE (b), 0ul) == 0 || mpfr_cmp_ui (MPC_IM (b), 0ul) == 0) { + /* Signs of zeroes may pose problems; delegate work to mpc_mul_fr */ + mpfr_t fr; + mpfr_init2 (fr, 2); + mpfr_set_ui (fr, 1ul, GMP_RNDN); + mpfr_div_2exp (fr, fr, c, GMP_RNDN); /* exact */ + inex = mpc_mul_fr (a, b, fr, rnd); + mpfr_clear (fr); + return inex; + } + else { + inex_re = mpfr_div_2exp (MPC_RE(a), MPC_RE(b), c, MPC_RND_RE(rnd)); + inex_im = mpfr_div_2exp (MPC_IM(a), MPC_IM(b), c, MPC_RND_IM(rnd)); + return MPC_INEX(inex_re, inex_im); + } } diff --git a/src/mul_2exp.c b/src/mul_2exp.c index 32ffffd..1674ff5 100644 --- a/src/mul_2exp.c +++ b/src/mul_2exp.c @@ -24,10 +24,21 @@ MA 02111-1307, USA. */ int mpc_mul_2exp (mpc_ptr a, mpc_srcptr b, unsigned long int c, mpc_rnd_t rnd) { - int inex_re, inex_im; - - inex_re = mpfr_mul_2exp (MPC_RE(a), MPC_RE(b), c, MPC_RND_RE(rnd)); - inex_im = mpfr_mul_2exp (MPC_IM(a), MPC_IM(b), c, MPC_RND_IM(rnd)); - - return MPC_INEX(inex_re, inex_im); + int inex_re, inex_im, inex; + + if (mpfr_cmp_ui (MPC_RE (b), 0ul) == 0 || mpfr_cmp_ui (MPC_IM (b), 0ul) == 0) { + /* Signs of zeroes may pose problems; delegate work to mpc_mul_fr */ + mpfr_t fr; + mpfr_init2 (fr, 2); + mpfr_set_ui (fr, 1ul, GMP_RNDN); + mpfr_mul_2exp (fr, fr, c, GMP_RNDN); /* exact */ + inex = mpc_mul_fr (a, b, fr, rnd); + mpfr_clear (fr); + return inex; + } + else { + inex_re = mpfr_mul_2exp (MPC_RE(a), MPC_RE(b), c, MPC_RND_RE(rnd)); + inex_im = mpfr_mul_2exp (MPC_IM(a), MPC_IM(b), c, MPC_RND_IM(rnd)); + return MPC_INEX(inex_re, inex_im); + } } diff --git a/src/mul_fr.c b/src/mul_fr.c index 88ddbb7..593ceda 100644 --- a/src/mul_fr.c +++ b/src/mul_fr.c @@ -20,25 +20,26 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "mpc-impl.h" +#include <stdio.h> int mpc_mul_fr (mpc_ptr a, mpc_srcptr b, mpfr_srcptr c, mpc_rnd_t rnd) { - int inex_re, inex_im; - mpfr_t real; + int inex_re, inex_im; + mpfr_t real; - if (c == MPC_RE (a)) - /* We have to use temporary variable. */ - mpfr_init2 (real, MPFR_PREC (MPC_RE (a))); - else - real [0] = MPC_RE (a) [0]; + if (c == MPC_RE (a)) + /* We have to use a temporary variable. */ + mpfr_init2 (real, MPFR_PREC (MPC_RE (a))); + else + real [0] = MPC_RE (a) [0]; - inex_re = mpfr_mul (real, MPC_RE(b), c, MPC_RND_RE(rnd)); - inex_im = mpfr_mul (MPC_IM(a), MPC_IM(b), c, MPC_RND_IM(rnd)); - mpfr_set (MPC_RE (a), real, GMP_RNDN); /* exact */ + inex_re = mpfr_mul (real, MPC_RE(b), c, MPC_RND_RE(rnd)); + inex_im = mpfr_mul (MPC_IM(a), MPC_IM(b), c, MPC_RND_IM(rnd)); + mpfr_set (MPC_RE (a), real, GMP_RNDN); /* exact */ - if (c == MPC_RE (a)) - mpfr_clear (real); + if (c == MPC_RE (a)) + mpfr_clear (real); - return MPC_INEX(inex_re, inex_im); + return MPC_INEX(inex_re, inex_im); } diff --git a/src/mul_i.c b/src/mul_i.c index b59f511..9c72170 100644 --- a/src/mul_i.c +++ b/src/mul_i.c @@ -1,4 +1,4 @@ -/* mpc_mul_si -- Multiply a complex number by plus or minus i. +/* mpc_mul_i -- Multiply a complex number by plus or minus i. Copyright (C) 2005, 2009 Andreas Enge, Philippe Th\'eveny @@ -76,6 +76,6 @@ mpc_mul_i (mpc_ptr a, mpc_srcptr b, int sign, mpc_rnd_t rnd) inex_im = mpfr_neg (MPC_IM (a), MPC_RE (b), MPC_RND_IM (rnd)); } } - - return MPC_INEX(inex_re, inex_im); + + return MPC_INEX(inex_re, inex_im); } diff --git a/src/mul_si.c b/src/mul_si.c index 49238f4..36b92f2 100644 --- a/src/mul_si.c +++ b/src/mul_si.c @@ -24,10 +24,21 @@ MA 02111-1307, USA. */ int mpc_mul_si (mpc_ptr a, mpc_srcptr b, long int c, mpc_rnd_t rnd) { - int inex_re, inex_im; - - inex_re = mpfr_mul_si (MPC_RE(a), MPC_RE(b), c, MPC_RND_RE(rnd)); - inex_im = mpfr_mul_si (MPC_IM(a), MPC_IM(b), c, MPC_RND_IM(rnd)); - - return MPC_INEX(inex_re, inex_im); + int inex_re, inex_im, inex; + + if (mpfr_cmp_ui (MPC_RE (b), 0ul) == 0 || mpfr_cmp_ui (MPC_IM (b), 0ul) == 0 + || c == 0) { + /* Signs of zeroes may pose problems; delegate work to mpc_mul_fr */ + mpfr_t fr; + mpfr_init2 (fr, 2); + mpfr_set_si (fr, c, GMP_RNDN); + inex = mpc_mul_fr (a, b, fr, rnd); + mpfr_clear (fr); + return inex; + } + else { + inex_re = mpfr_mul_si (MPC_RE(a), MPC_RE(b), c, MPC_RND_RE(rnd)); + inex_im = mpfr_mul_si (MPC_IM(a), MPC_IM(b), c, MPC_RND_IM(rnd)); + return MPC_INEX (inex_re, inex_im); + } } diff --git a/src/mul_ui.c b/src/mul_ui.c index 4487145..c2adbaa 100644 --- a/src/mul_ui.c +++ b/src/mul_ui.c @@ -24,10 +24,21 @@ MA 02111-1307, USA. */ int mpc_mul_ui (mpc_ptr a, mpc_srcptr b, unsigned long int c, mpc_rnd_t rnd) { - int inex_re, inex_im; - - inex_re = mpfr_mul_ui (MPC_RE(a), MPC_RE(b), c, MPC_RND_RE(rnd)); - inex_im = mpfr_mul_ui (MPC_IM(a), MPC_IM(b), c, MPC_RND_IM(rnd)); - - return MPC_INEX(inex_re, inex_im); + int inex_re, inex_im, inex; + + if (mpfr_cmp_ui (MPC_RE (b), 0ul) == 0 || mpfr_cmp_ui (MPC_IM (b), 0ul) == 0 + || c == 0) { + /* Signs of zeroes may pose problems; delegate work to mpc_mul_fr */ + mpfr_t fr; + mpfr_init2 (fr, 2); + mpfr_set_ui (fr, c, GMP_RNDN); + inex = mpc_mul_fr (a, b, fr, rnd); + mpfr_clear (fr); + return inex; + } + else { + inex_re = mpfr_mul_ui (MPC_RE(a), MPC_RE(b), c, MPC_RND_RE(rnd)); + inex_im = mpfr_mul_ui (MPC_IM(a), MPC_IM(b), c, MPC_RND_IM(rnd)); + return MPC_INEX(inex_re, inex_im); + } } @@ -49,7 +49,7 @@ MA 02111-1307, USA. */ whether c = -b^2, i.e., if -c is a square. Case 3: b = 0. Then d is necessarily zero, thus it suffices to check - whether c = a^2, i.e., if c is a square. + whether c = a^2, i.e., if c is a square. */ static int mpc_perfect_square_p (mpz_t a, mpz_t b, mpz_t c, mpz_t d) @@ -183,11 +183,11 @@ mpc_pow_exact (mpc_ptr z, mpc_srcptr x, mpfr_srcptr y, mpc_rnd_t rnd, } else /* neither c nor d is zero */ { - unsigned long u; + unsigned long v; t = mpz_scan1 (c, 0); - u = mpz_scan1 (d, 0); - if (u < t) - t = u; + v = mpz_scan1 (d, 0); + if (v < t) + t = v; mpz_div_2exp (c, c, t); mpz_div_2exp (d, d, t); ec += t; @@ -355,7 +355,7 @@ mpc_pow_exact (mpc_ptr z, mpc_srcptr x, mpfr_srcptr y, mpc_rnd_t rnd, /* Return 1 if y*2^k is an odd integer, 0 otherwise. Adapted from MPFR, file pow.c. - + Examples: with k=0, check if y is an odd integer, with k=1, check if y is half-an-integer, with k=-1, check if y/2 is an odd integer. @@ -430,7 +430,7 @@ mpc_pow (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd) mpfr_t n; int inex, cx1; int sign_zi; - /* cx1 < 0 if |x| < 1 + /* cx1 < 0 if |x| < 1 cx1 = 0 if |x| = 1 cx1 > 0 if |x| > 1 */ @@ -441,7 +441,7 @@ mpc_pow (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd) cx1 = -inex; sign_zi = (cx1 < 0 && mpfr_signbit (MPC_IM (y)) == 0) - || (cx1 == 0 + || (cx1 == 0 && mpfr_signbit (MPC_IM (x)) != mpfr_signbit (MPC_RE (y))) || (cx1 > 0 && mpfr_signbit (MPC_IM (y))); @@ -492,7 +492,7 @@ mpc_pow (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd) ret = mpc_set_ui (z, +1, rnd); /* the sign of the zero imaginary part is known in some cases (see - algorithm.tex). In such cases we have + algorithm.tex). In such cases we have (x +s*0i)^(y+/-0i) = x^y + s*sign(y)*0i where s = +/-1. We extend here this rule to fix the sign of the zero part. @@ -671,7 +671,7 @@ mpc_pow (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd) mpfr_t n; int inex, cx1; int sign_zi; - /* cx1 < 0 if |x| < 1 + /* cx1 < 0 if |x| < 1 cx1 = 0 if |x| = 1 cx1 > 0 if |x| > 1 */ @@ -682,7 +682,7 @@ mpc_pow (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd) cx1 = -inex; sign_zi = (cx1 < 0 && mpfr_signbit (MPC_IM (y)) == 0) - || (cx1 == 0 + || (cx1 == 0 && mpfr_signbit (MPC_IM (x)) != mpfr_signbit (MPC_RE (y))) || (cx1 > 0 && mpfr_signbit (MPC_IM (y))); |