diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2014-08-05 17:38:37 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2014-08-05 17:38:37 +0300 |
commit | eafb7b72c2b6095cba51a77f5f7a5240a658c55c (patch) | |
tree | 4b60eb71ac37bb58d3137d42442572e3e6288107 | |
parent | 2aff045eb07d96c572242287487450f1d9acc5fe (diff) | |
download | egawk-eafb7b72c2b6095cba51a77f5f7a5240a658c55c.tar.gz egawk-eafb7b72c2b6095cba51a77f5f7a5240a658c55c.tar.bz2 egawk-eafb7b72c2b6095cba51a77f5f7a5240a658c55c.zip |
Bug fix to MPFR mod operation for negative numerator.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | mpfr.c | 21 | ||||
-rw-r--r-- | test/Makefile.am | 9 | ||||
-rw-r--r-- | test/Makefile.in | 9 | ||||
-rw-r--r-- | test/mpfrrem.awk | 6 | ||||
-rw-r--r-- | test/mpfrrem.ok | 4 |
6 files changed, 55 insertions, 4 deletions
@@ -2,13 +2,21 @@ Bug fix: For MPFR sqrt(), need to set precision of result to be the same as that of the argument. Doesn't hurt other functions. - See test/mpfrsqrt.awk. + See test/mpfrsqrt.awk. Thank to Katie Wasserman <katie@wass.net> + for the bug report. * mpfr.c (do_mpfr_func): New function. Runs code for MPFR functions while still enabling debugging. Add call here to mpfr_set_prec(). Original code from SPEC_MATH macro. (SPEC_MATH): Change macro to call do_mpfr_func(). + Next MPFR bug fix: The % operator gave strange results for negative + numerator. Thanks again to Katie Wasserman for the bug report. + + * mpfr.c (mpg_mod): Use mpz_tdiv_qr() instead of mpz_mod(). From + the GMP doc, mpz_mod() should have worked; it's not clear why + it doesn't. + 2014-08-03 Arnold D. Robbins <arnold@skeeve.com> * builtin.c (format_tree): Don't need to check return value of @@ -1376,8 +1376,27 @@ mpg_mod(NODE *t1, NODE *t2) int tval; if (is_mpg_integer(t1) && is_mpg_integer(t2)) { + /* + * 8/2014: Originally, this was just + * + * r = mpg_integer(); + * mpz_mod(r->mpg_i, t1->mpg_i, t2->mpg_i); + * + * But that gave very strange results with negative numerator: + * + * $ ./gawk -M 'BEGIN { print -15 % 7 }' + * 6 + * + * So instead we use mpz_tdiv_qr() to get the correct result + * and just throw away the quotient. We could not find any + * reason why mpz_mod() wasn't working correctly. + */ + NODE *dummy_quotient; + r = mpg_integer(); - mpz_mod(r->mpg_i, t1->mpg_i, t2->mpg_i); + dummy_quotient = mpg_integer(); + mpz_tdiv_qr(dummy_quotient->mpg_i, r->mpg_i, t1->mpg_i, t2->mpg_i); + unref(dummy_quotient); } else { mpfr_ptr p1, p2; p1 = MP_FLOAT(t1); diff --git a/test/Makefile.am b/test/Makefile.am index 8349a73e..ede44523 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -529,6 +529,8 @@ EXTRA_DIST = \ mpfrnr.awk \ mpfrnr.in \ mpfrnr.ok \ + mpfrrem.awk \ + mpfrrem.ok \ mpfrrnd.awk \ mpfrrnd.ok \ mpfrsort.awk \ @@ -1024,7 +1026,7 @@ INET_TESTS = inetdayu inetdayt inetechu inetecht MACHINE_TESTS = double1 double2 fmtspcl intformat -MPFR_TESTS = mpfrnr mpfrnegzero mpfrrnd mpfrieee mpfrexprange \ +MPFR_TESTS = mpfrnr mpfrnegzero mpfrrem mpfrrnd mpfrieee mpfrexprange \ mpfrsort mpfrsqrt mpfrbigint LOCALE_CHARSET_TESTS = \ @@ -1752,6 +1754,11 @@ mpfrsqrt: @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1 @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +mpfrrem: + @echo $@ + @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1 + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + jarebug:: @echo $@ @"$(srcdir)"/$@.sh "$(AWKPROG)" "$(srcdir)"/$@.awk "$(srcdir)"/$@.in "_$@" diff --git a/test/Makefile.in b/test/Makefile.in index e8fd8844..196e125c 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -775,6 +775,8 @@ EXTRA_DIST = \ mpfrnr.awk \ mpfrnr.in \ mpfrnr.ok \ + mpfrrem.awk \ + mpfrrem.ok \ mpfrrnd.awk \ mpfrrnd.ok \ mpfrsort.awk \ @@ -1266,7 +1268,7 @@ GAWK_EXT_TESTS = \ EXTRA_TESTS = inftest regtest INET_TESTS = inetdayu inetdayt inetechu inetecht MACHINE_TESTS = double1 double2 fmtspcl intformat -MPFR_TESTS = mpfrnr mpfrnegzero mpfrrnd mpfrieee mpfrexprange \ +MPFR_TESTS = mpfrnr mpfrnegzero mpfrrem mpfrrnd mpfrieee mpfrexprange \ mpfrsort mpfrsqrt mpfrbigint LOCALE_CHARSET_TESTS = \ @@ -2176,6 +2178,11 @@ mpfrsqrt: @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1 @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +mpfrrem: + @echo $@ + @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1 + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + jarebug:: @echo $@ @"$(srcdir)"/$@.sh "$(AWKPROG)" "$(srcdir)"/$@.awk "$(srcdir)"/$@.in "_$@" diff --git a/test/mpfrrem.awk b/test/mpfrrem.awk new file mode 100644 index 00000000..fd8bc4d5 --- /dev/null +++ b/test/mpfrrem.awk @@ -0,0 +1,6 @@ +BEGIN { + print "15 % 7 =", 15 % 7 + print "15 % -7 =", 15 % -7 + print "-15 % 7 =", -15 % 7 + print "-15 % -7 =", -15 % -7 +} diff --git a/test/mpfrrem.ok b/test/mpfrrem.ok new file mode 100644 index 00000000..91010457 --- /dev/null +++ b/test/mpfrrem.ok @@ -0,0 +1,4 @@ +15 % 7 = 1 +15 % -7 = 1 +-15 % 7 = -1 +-15 % -7 = -1 |