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

  1. /*------------------------------------------------------------------------
  2.  * filename - atan2l.cas
  3.  *
  4.  * function(s)
  5.  *        atan2l - long double 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  NANINVTRIGL [5] = {0,0,0,0xC022, 0x7FFF};
  26.  
  27.  
  28. /*--------------------------------------------------------------------------*
  29.  
  30. Name            atan2l - trigonometric function
  31.  
  32. Usage           long double atan2l(long double y, long double x);
  33.  
  34. Prototype in    math.h
  35.  
  36. Description     atan2l  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    atan2l 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: atan2l(+0,-1) = +pi but atan2l(-0,-1) = -pi.
  46.  
  47. *---------------------------------------------------------------------------*/
  48. #pragma warn -rvl
  49. #pragma warn -use
  50. long double _FARFUNC atan2l (long double y, long double x)
  51. {
  52.  
  53. asm     FLD     LONGDOUBLE (x)
  54. asm     mov     ax, x [8]       /* select MSW of x ..   */
  55. asm     mov     bx, y [8]       /* .. and of y          */
  56. asm     shl     bx, 1           /* discard sign         */
  57. asm     FLD     LONGDOUBLE (y)
  58. asm     jz      at2_yIsZero
  59. asm     shl     ax, 1           /* discard sign         */
  60. asm     jz      at2_xIsZero
  61. asm     cmp     ax, 0FFFEh
  62. asm     jnb     at2_xIsInf
  63. asm     cmp     bx, 0FFFEh
  64. asm     jnb     at2_yIsInf
  65.  
  66. asm     FDIVRP  ST(1), ST(0)
  67.  
  68. #ifdef _Windows
  69.         _f87_ArcTan();
  70. #else
  71. asm     _FAST_  (_FATAN_)
  72. #endif
  73.  
  74. /* convert the simple answer to a four quadrant answer. */
  75.  
  76. at2_setQuad:
  77. asm     test    BY0 (x [9]), 80h                /* the sign bit */
  78. asm     jz      at2_end
  79.  
  80. asm     FLDPI
  81.  
  82. asm     test    BY0 (y [9]), 80h
  83. asm     jz      at2_2ndQuad
  84.  
  85. at2_3rdQuad:
  86. asm     FSUBP   ST(1), ST
  87. asm     jmp     short   at2_end
  88.  
  89. at2_2ndQuad:
  90. asm     FADDP   ST(1), ST
  91.  
  92. at2_end:
  93.         return;
  94.  
  95.  
  96. /*      Special cases.
  97. */
  98. at2_yIsZero:
  99. asm     rcl     cx, 1                   /* save sign of y = 0 */
  100. asm     shl     ax, 1
  101. asm     jz      at2_indeterminate       /* if both are zero     */
  102. asm     jc      at2_retPi               /* x<0, return Pi */
  103. asm     FSTP    ST(1)                   /* else y is result     */
  104. asm     jmp     short   at2_end
  105.  
  106. at2_retPi:                      /* y = 0, x < 0 */
  107. asm     FSTP    ST(0)           /* discard x and y */
  108. asm     FSTP    ST(0)
  109. asm     FLDPI                   /* and return PI */
  110. asm     shr     cx, 1           /* was y +0 or -0 ? */
  111. asm     jnc     at2_end
  112. asm     FCHS
  113. asm     jmp     short at2_end
  114.  
  115. at2_xIsZero:                            /* and y is not zero    */
  116.                                         /*      or              */
  117. at2_yIsInf:                             /* and x is finite      */
  118. asm     FSTP    ST(0)           /* discard x and y */
  119. asm     FSTP    ST(0)
  120. asm     FLD     tbyte ptr (piBy2)
  121. asm     test    BY0 (y [9]), 80h                /* check sign of Y */
  122. asm     jz      at2_HPi         /* positive - return PI/2 */
  123. asm     FCHS                    /* negative - return -PI/2 */
  124. at2_HPi:
  125. asm     jmp     short   at2_end
  126.  
  127. at2_xIsInf:
  128. asm     cmp     bx, 0FFFEh
  129. asm     jnb     at2_indeterminate       /* if both are infinite */
  130. asm     FSTP    ST(0)           /* discard x and y */
  131. asm     FSTP    ST(0)
  132. asm     FLDZ
  133. asm     jmp     short   at2_setQuad
  134.  
  135. /*
  136.   There are two cases considered irresolvable: both operands zero, or
  137.   both operands infinite.
  138. */
  139. at2_indeterminate:                      /* either equal or both infinite */
  140. asm     FSTP    ST(0)           /* discard x and y */
  141. asm     FSTP    ST(0)
  142. #pragma warn -ret
  143.         return __matherrl (DOMAIN, "atan2l", &x, &y,  *((long double *) NANINVTRIGL));
  144. #pragma warn .ret
  145. }
  146. #pragma warn .rvl
  147. #pragma warn .use
  148.