delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2009/09/14/18:26:45

X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f
X-Recipient: djgpp-workers AT delorie DOT com
X-Authenticated: #27081556
X-Provags-ID: V01U2FsdGVkX1/e+UlBzafe/Z2ARLACNnnyBrVQvNx66wRKJbjTlD
dEiJz/pghvnvWn
From: Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
To: djgpp-workers AT delorie DOT com
Subject: Re: atan2 bug
Date: Tue, 15 Sep 2009 00:25:37 +0200
User-Agent: KMail/1.9.10
References: <200909142122 DOT 34236 DOT juan DOT guerrero AT gmx DOT de> <83y6ohxos6 DOT fsf AT gnu DOT org>
In-Reply-To: <83y6ohxos6.fsf@gnu.org>
MIME-Version: 1.0
Message-Id: <200909150025.37854.juan.guerrero@gmx.de>
X-Y-GMX-Trusted: 0
X-FuHaFi: 0.42
Reply-To: djgpp-workers AT delorie DOT com

Am Montag, 14. September 2009 schrieb Eli Zaretskii:
[snip] 
> Do you have a test that actually trips it?  If so, how about adding it
> to tests/libc/ansi/math?
> 

Below is a test progran that will trigger the bug.
If y is positive finite and x is positive infinity then the result of atan2(y, x)
must be +0.0 but atan2 returns errno=1 and NaN as result.  The explanaition has
already be given in the previuos post.  If y is negative finite and x is negative
infinite the result must be -PI, but again errno=1 and result set to NaN.

Here is the original (offending) code snippet:

aby:
	movl	8(%esp), %eax		/* inf or NaN */    <==  loads mantissa high part of double y.
	testl	$0x000FFFFF, %eax
	jne	badarg			/* y = NaN */
	movl	4(%esp), %eax				    <==  loads mantissa low part of double y.
	testl	%eax, %eax
	jnz	badarg

	movl	16(%esp), %eax
	andl	$0x7FF00000,%eax
	cmpl	$0x7FF00000,%eax
	jne	argok			/* x is finite */
	jmp	badarg

abx:
	movl	16(%esp), %eax		/* inf or NaN */    <==  loads mantissa high part of double x.
	testl	$0x000FFFFF, %eax
	jnz	badarg
	movl	4(%esp), %eax				    <==  loads mantissa low part of double y instead of double x.
	testl	%eax, %eax
	jnz	badarg

	movl	8(%esp), %eax
	andl	$0x7FF00000,%eax
	cmpl	$0x7FF00000,%eax
	jne	argok			/* y is finite */


A quick inspection of the marked lines show that the test ist broken and will
never work properly.  Every time the 32 bits at 4(%esp) are different from zero
the value of x will be interpreted as NaN and this is simply wrong.  With this
code there is no way to identify x as infinite because the low part of the x-
mantissa is never evaluated.


Regards,
Juan M. Guerrero



2009-09-14  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>
	Diffs against djgpp CVS head of 2009-08-16.


	* src/libc/ansi/math/atan2.S: Check mantissa of y and not mantissa of x.





diff -aprNU5 djgpp.orig/src/libc/ansi/math/atan2.S djgpp/src/libc/ansi/math/atan2.S
--- djgpp.orig/src/libc/ansi/math/atan2.S	1999-08-04 19:58:20 +0000
+++ djgpp/src/libc/ansi/math/atan2.S	2009-09-15 00:16:18 +0000
@@ -45,12 +45,12 @@ aby:
 	jmp	badarg
 
 abx:
 	movl	16(%esp), %eax		/* inf or NaN */
 	testl	$0x000FFFFF, %eax
-	jnz	badarg
-	movl	4(%esp), %eax
+	jne	badarg			/* x = NaN */
+	movl	12(%esp), %eax
 	testl	%eax, %eax
 	jnz	badarg
 
 	movl	8(%esp), %eax
 	andl	$0x7FF00000,%eax
diff -aprNU5 djgpp.orig/tests/libc/ansi/math/elefunt/atan2.c djgpp/tests/libc/ansi/math/elefunt/atan2.c
--- djgpp.orig/tests/libc/ansi/math/elefunt/atan2.c	1970-01-01 00:00:00 +0000
+++ djgpp/tests/libc/ansi/math/elefunt/atan2.c	2009-09-15 00:12:56 +0000
@@ -0,0 +1,48 @@
+#include <libc/ieee.h>
+#include <stdio.h>
+#include <errno.h>
+#include <math.h>
+
+
+int main(void)
+{
+  _double_union_t x, y;
+  double result;
+
+  y.d = M_PI;
+  x.dt.sign      = 0;
+  x.dt.exponent  = 0x07FF;
+  x.dt.mantissah = 0x000000000;
+  x.dt.mantissal = 0x000000000;  /*  +Infinity.  */
+
+  /*
+   *  Compute atan of the quotient of a positive finite number with pos. infinite.
+   *  The result must be +0.0
+   */
+  errno = 0;
+  result = atan2(y.d, x.d);
+  if (errno)
+    printf("errno=%d\ny=%f  x=%f:  result=%f  result must be +0.0\n", errno, y.d, x.d, result);
+  else if (result == +0.0)
+    printf("test passed.\n");
+  else
+    printf("test failed.\n");
+
+
+  /*
+   *  Compute atan of the quotient of a negative finite number with pos. infinite.
+   *  The result must be -0.0
+   */
+  errno = 0;
+  y.dt.sign = 1;
+  x.dt.sign = 1;
+  result = atan2(y.d, x.d);
+  if (errno)
+    printf("errno=%d\ny=%f  x=%f:  result=%f  result must be -0.0\n", errno, y.d, x.d, result);
+  else if (result == -M_PI)
+    printf("test passed.\n");
+  else
+    printf("test failed.\n");
+
+  return 0;
+}
diff -aprNU5 djgpp.orig/tests/libc/ansi/math/elefunt/makefile djgpp/tests/libc/ansi/math/elefunt/makefile
--- djgpp.orig/tests/libc/ansi/math/elefunt/makefile	2003-04-20 14:10:34 +0000
+++ djgpp/tests/libc/ansi/math/elefunt/makefile	2009-09-15 00:16:18 +0000
@@ -98,11 +98,12 @@ TARGETS = \
 	tpower.$(LOG) \
 	tsin.$(LOG)   \
 	tsinh.$(LOG)  \
 	tsqrt.$(LOG)  \
 	ttan.$(LOG)   \
-	ttanh.$(LOG)
+	ttanh.$(LOG)  \
+	atan2.$(LOG)
 
 # $(EXECUTABLES) = $(TARGETS:/s/.$(LOG)/$(EXE))
 
 all ::    $(TARGETS)
 	@rem.com
@@ -120,11 +121,11 @@ summary:
 	egrep "^1|ESTIMATED LOSS" *$(LOG)
 
 clean:
 	$(RM) *.o *.obj *.bak *.exe
 	$(RM) talog tasin tatan texp tpower tsin tsinh
-	$(RM) tsqrt ttan ttanh tmacha
+	$(RM) tsqrt ttan ttanh tmacha atan2
 
 realclean : clean       # delete log files, too
 	$(RM) *.djl *.bcl *.tcl
 ifdef BORLAND
 tmacha$(EXE):	tmacha.$(OE) $(OBJS)
@@ -180,10 +181,12 @@ tsqrt$(EXE):	msqrt.$(OE) tsqrt.$(OE) $(O
 	$(LD) $(LDFLAGS) $(OUT) $@ $^ $(LIBS)
 ttan$(EXE):	mtan.$(OE) ttan.$(OE) $(OBJS)
 	$(LD) $(LDFLAGS) $(OUT) $@ $^ $(LIBS)
 ttanh$(EXE):	mtanh.$(OE) ttanh.$(OE) $(OBJS)
 	$(LD) $(LDFLAGS) $(OUT) $@ $^ $(LIBS)
+tatan2$(EXE):	atan2.$(OE)
+	$(LD) $(LDFLAGS) $(OUT) $@ $^ $(LIBS)
 endif
 
 # dependencies found by gcc -MM *.c
 
 tpower.$(OE) : tpower.c elefunt.h
@@ -195,10 +198,11 @@ tsinh.$(OE) : tsinh.c elefunt.h
 tsqrt.$(OE) : tsqrt.c elefunt.h
 ttan.$(OE) : ttan.c elefunt.h
 ttanh.$(OE) : ttanh.c elefunt.h
 tmacha.$(OE) : tmacha.c elefunt.h
 atan.$(OE) : atan.c
+atan2.$(OE) : atan2.c
 exp.$(OE) : exp.c
 ipow.$(OE) : ipow.c elefunt.h
 ldexp.$(OE) : ldexp.c
 tsmach.$(OE) : tsmach.c elefunt.h
 malog.$(OE) : malog.c elefunt.h

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019