[7] in Athena Bugs

home help back first fref pref prev next nref lref last post

A bug with atan2(y,x)

daemon@ATHENA.MIT.EDU (Jim Rees)
Wed Mar 9 23:37:05 1988

To: bugs@ATHENA.MIT.EDU
Date: Tue, 08 Mar 88 10:48:41 EST
From: Jim Rees <jnrees@ATHENA.MIT.EDU>
Name of person who discovered the bug:Jim Rees
Their Athena Login ID:jnrees
------------------------------------------------------------------------
A brief synopsis of the problem:
The C function 'double atan2(y,x)' seems to result in 'Illegal
Instruction' on occasion. 

I wrote some software which handles complex number manipulation and it
uses atan2 to compute the angle of a number given it's real and
imaginary parts.  On a run which involves a great deal of manipulation
(using Newton's method to find roots of polynomials), an 'Illegal
Instruction' error is generated by the atan2 function.  

--This is DBX output---
Illegal instruction (reserved operand fault) in rect_to_pol at line 54
in file "complex.c"
   54         c2.b = atan2(c.b,c.a);
(dbx) print c.b
-2.93874e-39 
(dbx) print c.a
1.0 
(dbx) print c.b/c.a
[internal error: size 8 in popsmall]
(I don't know if that last evaluation means anything)
-------------------------

I also ran the uncompiled code through saber and the error did not
occur.   When I ran the compiled code through saber the following
error was returned:
Signal 4: SIGILL    /* illegal instruction */
SIGILL code of: 'ILL_RESOP_FAULT    /* reserved operand fault */'
Stopped in rect_to_pol(c = Saber internal (builtin function) error (signal 10).
 (internal location 0x3bbfc)
Trying to abort.

Aborting.
Resetting to break level #1.
   53:       c2.a = hypot(c.a,c.b);
*  54:       c2.b = atan2(c.b,c.a);
*** signal #4 (SIGILL) occurred ***
   55:       c2.rect = POLAR;
(break 1) 4 -> c.b;
(double) -2.938736e-39
(break 1) 5 -> c.a;
(double) 1.000000e+00
(break 1) 6 -> 

Plus, I typed in these expressions, as a test:

2 -> double a,b;
3 -> a = 1.0;
(double) 1.000000e+00
4 -> b = -2.93874e-39;
(double) 0.000000e+00
5 -> b/a;
(double) 0.000000e+00
6 -> atan2(b,a);
Linking from /usr/lib/libm.a ...Linking completed.
(double) 0.000000e+00
7 -> 

So the saber interpreter seems to think that the small number
-2.93874e-39 equals 0.

I was able to fix the problem by writing my own atan2 function:

double myatan2(y,x)
     double x,y;
{
  double ans;
  if(x==0.){
    if(y==0.) ans = 0.;
    else if(y>0.) ans = PI/2.;
    else ans = -PI/2.;
  }
  else if(y == 0.){
    if(x < 0.) ans = PI;
    else ans = 0.;
  }
  else if(x > 0.) ans = atan(y/x);
  else ans = PI + atan(y/x);
  return(ans);
}

When I call myatan2 instead of atan2 the error never occurs.

So the problem may be relatively minor, but having to re-write a
procedure which is documented in the math man pages is somewhat
inconvenient.


				Jim Rees

home help back first fref pref prev next nref lref last post