### Re: Ambiguity in FATAN2

by **Ed** » Thu, 19 Mar 2009 11:15:57 GMT

avid N. Williams wrote:

When implementing FATAN2 a year ago, I wrote a test and

compared the results against several forths and MS-Fortran.

That's when I found discrepancies in the angle returned.

With some mathematical functions the result can be expressed

in alternate ways. IMO, a computer language standard should

define functions with a uniform result - else it just creates

complication for programmers. If one form isn't adequate,

then define two functions.

Below are cleaned-up versions of the test I used. It interrogates

all quadrants but has no provision for nan, inf etc. as these are

machine dependent. Included is a high-level FATAN2 which

works equally with floats on the data stack.

\ include FPOUT.F \ for F.R - refer http://dxforth.webhop.org/forth

0 [if] cr .( re-defining FATAN2 ...) cr

3.1415926535897932e fconstant PI

: FATAN2 ( y x -- r )

fdup f0< >r

fdup f0= if

fswap f<

if [ 0.5e pi f* ] fliteral

else [ -0.5e pi f* ] fliteral

then

else

f/ fatan

then

r> if

pi fover f0> if f- else f+ then

then ;

[then]

: .OUT ( x y -- ) cr

fover 1 10 f.r

fdup 1 10 f.r

fswap fatan2 8 20 f.r ;

cr cr

.( x y ATAN2)

cr

1e 0e .out

1e 1e .out

0e 1e .out

-1e 1e .out

cr

-1e 0e .out

-1e -1e .out

0e -1e .out

1e -1e .out

cr

\ 0e 0e .out .( *ambiguous condition* )

cr

real*8 x, y, z

write(*, 10)

write(*, 20)

x = 1

y = 0

z = atan2(y,x)

write(*, 30) x, y, z

x = 1

y = 1

z = atan2(y,x)

write(*, 30) x, y, z

x = 0

y = 1

z = atan2(y,x)

write(*, 30) x, y, z

x = -1

y = 1

z = atan2(y,x)

write(*, 30) x, y, z

write(*, 20)

x = -1

y = 0

z = atan2(y,x)

write(*, 30) x, y, z

x = -1

y = -1

z = atan2(y,x)

write(*, 30) x, y, z

x = 0

y = -1

z = atan2(y,x)

write(*, 30) x, y, z

x = 1

y = -1

z = atan2(y,x)

write(*, 30) x, y, z

write(*, 20)

C x = 0

C y = 0

C z = atan2(y,x)

C write(*, 30) x, y, z

10 format(' x y ATAN2')

20 format()

30 format(1x, 0pf10.1, 0pf10.1, 0pf20.8)

end

MS-Fortran 5.1:

x y ATAN2

1.0 .0 .00000000

1.0 1.0 .78539816

.0 1.0 1.57079633

-1.0 1.0 2.35619449

-1.0 .0 3.14159265

-1.0 -1.0 -2.35619449

.0 -1.0 -1.57079633

1.0 -1.0 -.78539816

SwiftForth 3:

x y ATAN2

1.0 0.0 0.00000000

1.0 1.0 0.78539816

0.0 1.0 1.57079630

-1.0 1.0 2.35619440

-1.0 0.0 3.14159260

-1.0 -1.0 3.92699080

0.0 -1.0 4.71238890

1.0 -1.0 5.49778710

VFX 4 (Ndp387.fth): \ seems to want x/y reversed

x y ATAN2

1.0 0.0 1.57079630

1.0 1.0 0.78539816

0.0 1.0 0.00000000

-1.0 1.0