summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2014-01-19 21:36:37 +0200
committerArnold D. Robbins <arnold@skeeve.com>2014-01-19 21:36:37 +0200
commit20ca1d1ba6e46f116e2dc169d263fd548b9bd074 (patch)
tree74d46c4cf0ecf8704df7d4dde7138ee0e131d1ec
parent9092450b4459af490e4d52ad3188d3282f36f726 (diff)
downloadgawk-20ca1d1ba6e46f116e2dc169d263fd548b9bd074.tar.gz
Fix -0 for MPFR.
-rw-r--r--ChangeLog5
-rw-r--r--awkgram.c31
-rw-r--r--awkgram.y31
-rw-r--r--test/ChangeLog5
-rw-r--r--test/Makefile.am10
-rw-r--r--test/Makefile.in11
-rw-r--r--test/mpfrnegzero.awk15
-rw-r--r--test/mpfrnegzero.ok9
8 files changed, 101 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index a5989414..d75916f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-01-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (negate_num): Handle the case of -0 for MPFR; the sign
+ was getting lost. Thanks to Hermann Peifer for the report.
+
2014-01-18 Arnold D. Robbins <arnold@skeeve.com>
* dfa.c (parse_bracket_exp): Sync with GNU grep, which now uses
diff --git a/awkgram.c b/awkgram.c
index 7eff2f11..657a1627 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -4512,16 +4512,33 @@ getfname(NODE *(*fptr)(int))
void
negate_num(NODE *n)
{
+ int tval = 0;
+
+ if (! is_mpg_number(n))
+ n->numbr = -n->numbr;
#ifdef HAVE_MPFR
- if (is_mpg_float(n)) {
- int tval;
- tval = mpfr_neg(n->mpg_numbr, n->mpg_numbr, ROUND_MODE);
+ else if (is_mpg_integer(n)) {
+ if (! iszero(n)) {
+ mpz_neg(n->mpg_i, n->mpg_i);
+ return;
+ }
+
+ /*
+ * 0 --> -0 conversion. Requires turning the MPG integer
+ * into an MPFR float.
+ *
+ * So, convert and fall through.
+ */
+ tval = mpfr_set_d(n->mpg_numbr, 0.0, ROUND_MODE);
IEEE_FMT(n->mpg_numbr, tval);
- } else if (is_mpg_integer(n)) {
- mpz_neg(n->mpg_i, n->mpg_i);
- } else
+ n->flags &= ~MPZN;
+ n->flags |= MPFN;
+ }
+
+ /* mpfr float case */
+ tval = mpfr_neg(n->mpg_numbr, n->mpg_numbr, ROUND_MODE);
+ IEEE_FMT(n->mpg_numbr, tval);
#endif
- n->numbr = -n->numbr;
}
/* print_included_from --- print `Included from ..' file names and locations */
diff --git a/awkgram.y b/awkgram.y
index 5846c134..fd83d6db 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -1964,16 +1964,33 @@ getfname(NODE *(*fptr)(int))
void
negate_num(NODE *n)
{
+ int tval = 0;
+
+ if (! is_mpg_number(n))
+ n->numbr = -n->numbr;
#ifdef HAVE_MPFR
- if (is_mpg_float(n)) {
- int tval;
- tval = mpfr_neg(n->mpg_numbr, n->mpg_numbr, ROUND_MODE);
+ else if (is_mpg_integer(n)) {
+ if (! iszero(n)) {
+ mpz_neg(n->mpg_i, n->mpg_i);
+ return;
+ }
+
+ /*
+ * 0 --> -0 conversion. Requires turning the MPG integer
+ * into an MPFR float.
+ *
+ * So, convert and fall through.
+ */
+ tval = mpfr_set_d(n->mpg_numbr, 0.0, ROUND_MODE);
IEEE_FMT(n->mpg_numbr, tval);
- } else if (is_mpg_integer(n)) {
- mpz_neg(n->mpg_i, n->mpg_i);
- } else
+ n->flags &= ~MPZN;
+ n->flags |= MPFN;
+ }
+
+ /* mpfr float case */
+ tval = mpfr_neg(n->mpg_numbr, n->mpg_numbr, ROUND_MODE);
+ IEEE_FMT(n->mpg_numbr, tval);
#endif
- n->numbr = -n->numbr;
}
/* print_included_from --- print `Included from ..' file names and locations */
diff --git a/test/ChangeLog b/test/ChangeLog
index 1da74f8a..535f6f14 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,8 @@
+2014-01-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (mpfrnegzero): New test.
+ * mpfrnegzero.awk, mpfrnegzero.ok: New files.
+
2014-01-17 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.am: Quote instances of $(top_srcdir) also.
diff --git a/test/Makefile.am b/test/Makefile.am
index 5a0c5a63..b6390009 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -522,6 +522,8 @@ EXTRA_DIST = \
mpfrexprange.ok \
mpfrieee.awk \
mpfrieee.ok \
+ mpfrnegzero.awk \
+ mpfrnegzero.ok \
mpfrnr.awk \
mpfrnr.in \
mpfrnr.ok \
@@ -1007,7 +1009,8 @@ INET_TESTS = inetdayu inetdayt inetechu inetecht
MACHINE_TESTS = double1 double2 fmtspcl intformat
-MPFR_TESTS = mpfrnr mpfrrnd mpfrieee mpfrexprange mpfrsort mpfrbigint
+MPFR_TESTS = mpfrnr mpfrnegzero mpfrrnd mpfrieee mpfrexprange \
+ mpfrsort mpfrbigint
LOCALE_CHARSET_TESTS = \
asort asorti backbigs1 backsmalls1 backsmalls2 \
@@ -1695,6 +1698,11 @@ mpfrrnd:
@$(AWK) -M -vPREC=53 -f "$(srcdir)"/$@.awk > _$@ 2>&1
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+mpfrnegzero:
+ @echo $@
+ @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
mpfrnr:
@echo $@
@$(AWK) -M -vPREC=113 -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in > _$@
diff --git a/test/Makefile.in b/test/Makefile.in
index d0d527f4..fd0484a8 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -768,6 +768,8 @@ EXTRA_DIST = \
mpfrexprange.ok \
mpfrieee.awk \
mpfrieee.ok \
+ mpfrnegzero.awk \
+ mpfrnegzero.ok \
mpfrnr.awk \
mpfrnr.in \
mpfrnr.ok \
@@ -1249,7 +1251,9 @@ GAWK_EXT_TESTS = \
EXTRA_TESTS = inftest regtest
INET_TESTS = inetdayu inetdayt inetechu inetecht
MACHINE_TESTS = double1 double2 fmtspcl intformat
-MPFR_TESTS = mpfrnr mpfrrnd mpfrieee mpfrexprange mpfrsort mpfrbigint
+MPFR_TESTS = mpfrnr mpfrnegzero mpfrrnd mpfrieee mpfrexprange \
+ mpfrsort mpfrbigint
+
LOCALE_CHARSET_TESTS = \
asort asorti backbigs1 backsmalls1 backsmalls2 \
fmttest fnarydel fnparydl jarebug lc_num1 mbfw1 \
@@ -2118,6 +2122,11 @@ mpfrrnd:
@$(AWK) -M -vPREC=53 -f "$(srcdir)"/$@.awk > _$@ 2>&1
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+mpfrnegzero:
+ @echo $@
+ @$(AWK) -M -f "$(srcdir)"/$@.awk > _$@ 2>&1
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
mpfrnr:
@echo $@
@$(AWK) -M -vPREC=113 -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in > _$@
diff --git a/test/mpfrnegzero.awk b/test/mpfrnegzero.awk
new file mode 100644
index 00000000..cc6bf65b
--- /dev/null
+++ b/test/mpfrnegzero.awk
@@ -0,0 +1,15 @@
+BEGIN {
+ printf("-0 -> %f, -0.0 -> %f\n", -0, -0.0)
+
+ printf("atan2(+0, -0) = %f\n", atan2(+0, -0))
+ printf("atan2(+0.0, -0.0) = %f\n", atan2(+0.0, -0.0))
+
+ printf("atan2(-0, -0) = %f\n", atan2(-0, -0))
+ printf("atan2(-0.0, -0.0) = %f\n", atan2(-0.0, -0.0))
+
+ printf("atan2(+0, +0) = %f\n", atan2(+0, +0))
+ printf("atan2(+0.0, +0.0) = %f\n", atan2(+0.0, +0.0))
+
+ printf("atan2(-0, +0) = %f\n", atan2(-0, +0))
+ printf("atan2(-0.0, +0.0) = %f\n", atan2(-0.0, +0.0))
+}
diff --git a/test/mpfrnegzero.ok b/test/mpfrnegzero.ok
new file mode 100644
index 00000000..7af16292
--- /dev/null
+++ b/test/mpfrnegzero.ok
@@ -0,0 +1,9 @@
+-0 -> -0.000000, -0.0 -> -0.000000
+atan2(+0, -0) = 3.141593
+atan2(+0.0, -0.0) = 3.141593
+atan2(-0, -0) = -3.141593
+atan2(-0.0, -0.0) = -3.141593
+atan2(+0, +0) = 0.000000
+atan2(+0.0, +0.0) = 0.000000
+atan2(-0, +0) = -0.000000
+atan2(-0.0, +0.0) = -0.000000