home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 2.ddi / MATHSRC.ZIP / ATAN2.CAS < prev    next >
Encoding:
Text File  |  1992-06-10  |  4.3 KB  |  151 lines

  1. /*------------------------------------------------------------------------
  2.  * filename - atan2.cas
  3.  *
  4.  * function(s)
  5.  *        atan2 - trigonometric function
  6.  *-----------------------------------------------------------------------*/
  7.  
  8. /*
  9.  *      C/C++ Run Time Library - Version 5.0
  10.  *
  11.  *      Copyright (c) 1987, 1992 by Borland International
  12.  *      All Rights Reserved.
  13.  *
  14.  */
  15.  
  16.  
  17. #pragma inline
  18. #include <asmrules.h>
  19.  
  20. #include <_math.h>
  21. #include <math.h>
  22. #include <errno.h>
  23.  
  24. static  unsigned short  piBy2 [] = {0xC235, 0x2168, 0xDAA2, 0xC90F, 0x3FFF};
  25. static  unsigned short  NANINVTRIG [4] = {0,0,0x0440, 0x7FF8};
  26.  
  27.  
  28. /*--------------------------------------------------------------------------*
  29.  
  30. Name            atan2 - trigonometric function
  31.  
  32. Usage           double atan2(double y, double x);
  33.  
  34. Prototype in    math.h
  35.  
  36. Description     atan2  returns the  arc tangent   of y/x  and will  produce
  37.                 correct results even  when resulting is near pi/2  or -pi/2
  38.                 (x near 0).
  39.  
  40. Return value    atan2 returns a value in the range -pi to pi.
  41.                 If a ratio of 0/0  is supplied then _RANGE_VAL is returned
  42.                 and errno is set to:
  43.                         EDOM Domain error
  44.  
  45. Caution: atan2(+0,-1) = +pi but atan2(-0,-1) = -pi.
  46.  
  47. *---------------------------------------------------------------------------*/
  48. #pragma warn -rvl
  49. #pragma warn -use
  50.  
  51. double _FARFUNC atan2( double y, double x )
  52. {
  53.  
  54. asm     FLD     DOUBLE (x)
  55. asm     mov     ax, x [6]       /* select MSW of x ..   */
  56. asm     and     al, 0F0h        /* ignore fraction      */
  57. asm     mov     bx, y [6]       /* .. and of y          */
  58. asm     and     bl, 0F0h
  59. asm     shl     bx, 1           /* discard sign         */
  60. asm     FLD     DOUBLE (y)
  61. asm     jz      at2_yIsZero
  62. asm     shl     ax, 1           /* discard sign         */
  63. asm     jz      at2_xIsZero
  64. asm     cmp     ax, 0FFE0h
  65. asm     jnb     at2_xIsInf
  66. asm     cmp     bx, 0FFE0h
  67. asm     jnb     at2_yIsInf
  68.  
  69. asm     FDIVRP  ST(1), ST(0)
  70.  
  71. #ifdef _Windows
  72.         _f87_ArcTan();
  73. #else
  74. asm     _FAST_  (_FATAN_)
  75. #endif
  76.  
  77. /* convert the simple answer to a four quadrant answer. */
  78.  
  79. at2_setQuad:
  80. asm     test    BY0 (x [7]), 80h                /* the sign bit */
  81. asm     jz      at2_end
  82.  
  83. asm     FLDPI
  84.  
  85. asm     test    BY0 (y [7]), 80h
  86. asm     jz      at2_2ndQuad
  87.  
  88. at2_3rdQuad:
  89. asm     FSUBP   ST(1), ST
  90. asm     jmp     short   at2_end
  91.  
  92. at2_2ndQuad:
  93. asm     FADDP   ST(1), ST
  94.  
  95. at2_end:
  96.         return;
  97.  
  98.  
  99. /*      Special cases.
  100. */
  101. at2_yIsZero:
  102. asm     rcl     cx, 1                   /* save sign of y = 0 */
  103. asm     shl     ax, 1
  104. asm     jz      at2_indeterminate       /* if both are zero     */
  105. asm     jc      at2_retPi               /* x<0, return Pi */
  106. asm     FSTP    ST(1)                   /* else y is result     */
  107. asm     jmp     short   at2_end
  108.  
  109. at2_retPi:                      /* y = 0, x < 0 */
  110. asm     FSTP    ST(0)           /* discard x and y */
  111. asm     FSTP    ST(0)
  112. asm     FLDPI                   /* and return PI */
  113. asm     shr     cx, 1           /* was y +0 or -0 ? */
  114. asm     jnc     at2_end
  115. asm     FCHS
  116. asm     jmp     short at2_end
  117.  
  118. at2_xIsZero:                            /* and y is not zero    */
  119.                                         /*      or              */
  120. at2_yIsInf:                             /* and x is finite      */
  121. asm     FSTP    ST(0)           /* discard x and y */
  122. asm     FSTP    ST(0)
  123. asm     FLD     tbyte ptr (piBy2)
  124. asm     test    BY0 (y [7]), 80h                /* check sign of Y */
  125. asm     jz      at2_HPi         /* positive - return PI/2 */
  126. asm     FCHS                    /* negative - return -PI/2 */
  127. at2_HPi:
  128. asm     jmp     short   at2_end
  129.  
  130. at2_xIsInf:
  131. asm     cmp     bx, 0FFE0h
  132. asm     jnb     at2_indeterminate       /* if both are infinite */
  133. asm     FSTP    ST(0)           /* discard x and y */
  134. asm     FSTP    ST(0)
  135. asm     FLDZ
  136. asm     jmp     short   at2_setQuad
  137.  
  138. /*
  139.   There are two cases considered irresolvable: both operands zero, or
  140.   both operands infinite.
  141. */
  142. at2_indeterminate:                      /* either equal or both infinite */
  143. asm     FSTP    ST(0)           /* discard x and y */
  144. asm     FSTP    ST(0)
  145. #pragma warn -ret
  146.         return _matherr (DOMAIN, "atan2", &x, &y,  *((double *) NANINVTRIG));
  147. #pragma warn .ret
  148. }
  149. #pragma warn .rvl
  150. #pragma warn .use
  151.