home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------
- * filename - atan2.cas
- *
- * function(s)
- * atan2 - trigonometric function
- *-----------------------------------------------------------------------*/
-
- /*[]------------------------------------------------------------[]*/
- /*| |*/
- /*| Turbo C Run Time Library - Version 3.0 |*/
- /*| |*/
- /*| |*/
- /*| Copyright (c) 1987, 1990 by Borland International |*/
- /*| All Rights Reserved. |*/
- /*| |*/
- /*[]------------------------------------------------------------[]*/
-
-
- #pragma inline
- #include <asmrules.h>
-
- #include <_math.h>
- #include <math.h>
- #include <errno.h>
-
- static unsigned short piBy2 [] = {0xC235, 0x2168, 0xDAA2, 0xC90F, 0x3FFF};
- static unsigned short NANINVTRIG [4] = {0,0,0x0440, 0x7FF0};
-
-
- /*--------------------------------------------------------------------------*
-
- Name atan2 - trigonometric function
-
- Usage double atan2(double y, double x);
-
- Prototype in math.h
-
- Description atan2 returns the arc tangent of y/x and will produce
- correct results even when resulting is near pi/2 or -pi/2
- (x near 0).
-
- Return value atan2 returns a value in the range -pi to pi.
- If a ratio of 0/0 is supplied then _RANGE_VAL is returned
- and errno is set to:
- EDOM Domain error
-
- Caution: atan2(+0,-1) = +pi but atan2(-0,-1) = -pi.
-
- *---------------------------------------------------------------------------*/
- #pragma warn -rvl
- #pragma warn -use
- double atan2 (double y, double x)
- {
-
- asm FLD DOUBLE (x)
- asm mov ax, x [6] /* select MSW of x .. */
- asm and al, 0F0h /* ignore fraction */
- asm mov bx, y [6] /* .. and of y */
- asm and bl, 0F0h
- asm shl bx, 1 /* discard sign */
- asm FLD DOUBLE (y)
- asm jz at2_yIsZero
- asm shl ax, 1 /* discard sign */
- asm jz at2_xIsZero
- asm cmp ax, 0FFE0h
- asm jnb at2_xIsInf
- asm cmp bx, 0FFE0h
- asm jnb at2_yIsInf
-
- asm FDIVRP ST(1), ST(0)
- asm _FAST_ (_FATAN_)
-
- /* convert the simple answer to a four quadrant answer. */
-
- at2_setQuad:
- asm test BY0 (x [7]), 80h /* the sign bit */
- asm jz at2_end
-
- asm FLDPI
-
- asm test BY0 (y [7]), 80h
- asm jz at2_2ndQuad
-
- at2_3rdQuad:
- asm FSUBP ST(1), ST
- asm jmp short at2_end
-
- at2_2ndQuad:
- asm FADDP ST(1), ST
-
- at2_end:
- return;
-
-
- /* Special cases.
- */
- at2_yIsZero:
- asm rcl cx, 1 /* save sign of y = 0 */
- asm shl ax, 1
- asm jz at2_indeterminate /* if both are zero */
- asm jc at2_retPi /* x<0, return Pi */
- asm FSTP ST(1) /* else y is result */
- asm jmp short at2_end
-
- at2_retPi: /* y = 0, x < 0 */
- asm FCOMPP /* discard x and y */
- asm FLDPI /* and return PI */
- asm shr cx, 1 /* was y +0 or -0 ? */
- asm jnc at2_end
- asm FCHS
- asm jmp short at2_end
-
- at2_xIsZero: /* and y is not zero */
- /* or */
- at2_yIsInf: /* and x is finite */
- asm FCOMPP /* discard x and y */
- asm FLD tbyte ptr (piBy2)
- asm test BY0 (y [7]), 80h /* check sign of Y */
- asm jz at2_HPi /* positive - return PI/2 */
- asm FCHS /* negative - return -PI/2 */
- at2_HPi:
- asm jmp short at2_end
-
- at2_xIsInf:
- asm cmp bx, 0FFE0h
- asm jnb at2_indeterminate /* if both are infinite */
- asm FCOMPP /* discard x and y */
- asm FLDZ
- asm jmp short at2_setQuad
-
- /*
- There are two cases considered irresolvable: both operands zero, or
- both operands infinite.
- */
- at2_indeterminate: /* either equal or both infinite */
- asm FCOMPP /* discard x and y */
- #pragma warn -ret
- return _matherr (DOMAIN, "atan2", &x, &y, *((double *) NANINVTRIG));
- #pragma warn .ret
- }
- #pragma warn .rvl
- #pragma warn .use
-