home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c065 / 2.ddi / MATH.ZIP / ATAN2.CAS < prev    next >
Encoding:
Text File  |  1990-06-07  |  3.8 KB  |  143 lines

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