386atan.inc
来自「开放源码的编译器open watcom 1.6.0版的源代码」· INC 代码 · 共 380 行 · 第 1/2 页
INC
380 行
;*****************************************************************************
;*
;* Open Watcom Project
;*
;* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;* ========================================================================
;*
;* This file contains Original Code and/or Modifications of Original
;* Code as defined in and that are subject to the Sybase Open Watcom
;* Public License version 1.0 (the 'License'). You may not use this file
;* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;* provided with the Original Code and Modifications, and is also
;* available at www.sybase.com/developer/opensource.
;*
;* The Original Code and all software distributed under the License are
;* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;* NON-INFRINGEMENT. Please see the License for the specific language
;* governing rights and limitations under the License.
;*
;* ========================================================================
;*
;* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
;* DESCRIBE IT HERE!
;*
;*****************************************************************************
modstart 386atan
xref __FLDAC ; add constant from stack
xref __FLDD ; divide
xref ___LDA ; add
xref ___LDD ; divide
xref ___LDM ; multiply
xref __OddPoly ; evaluate polynomial
xdefp __fpatan ; calc atan2(y,x)
;;/*
;; atan - compute arctangent
;;
;; Uses the following identities
;; *****************************
;;
;; arctan(x) = - arctan( - x )
;;
;; arctan(x) = pi/2 - arctan( 1/x )
;;
;; arctan(x) = arctan( (x*sqrt(3)-1) / (x+sqrt(3)) ) + pi/6
;;*/
;;
;;#include <math.h>
;;#include "pi.h"
;;
;;#define FALSE 0
;;#define TRUE 1
;;
;;tan15 dt 0.2679491924311227
;;sqrt3:
;; dt 1.7320508075688772936
;;
;;extern int _sgn(double); /* get sign of x */
;;extern double _OddPoly(double, double *, int);
;;
;;
;;static double AtanPoly[] = {
align 2
AtanPoly dt 0.0443895157187
dt -0.06483193510303
dt 0.0767936869066
dt -0.0909037114191074 ; -0.09090371144275426
dt 0.11111097898051048
dt -0.14285714102825545
dt 0.1999999999872945
dt -0.3333333333332993
dt 1.0
;;};
;;double atan2( double y, double x ) - compute arctan(y/x)
;;
;;NOTE: x,y cannot both be 0
;;
;;case 1: y = 0 if x < 0 return pi, otherwise return 0
;;
;;case 2: x = 0 if y < 0 return -pi/2, otherwise return pi/2
;;
;;otherwise: compute z = atan( y/x )
;; if y >= 0 and z < 0 return z + pi
;; if y < 0 and z > 0 return z - pi
;; else return z
;;
;;double atan2( double y, double x )
;;/********************************/
;; {
;; register int sgnx; /* sgn(x) */
;; register int sgny; /* sgn(y) */
;;
;; sgny = _sgn( y );
;; sgnx = _sgn( x );
;; if( sgny == 0 ) { /* case 1 */
;; if( sgnx == 0 ) {
;; x = _matherr( DOMAIN, "atan2", &y, &x, 0.0 );
;; } else if( sgnx < 0 ) {
;; x = Pi;
;; } else {
;; x = 0.0;
;; }
;; } else if( sgnx == 0 ) { /* case 2 */
;; if( sgny < 0 ) {
;; x = -Piby2;
;; } else {
;; x = Piby2;
;; }
;; } else {
;; x = atan( y / x );
;; sgnx = _sgn( x );
;; if( sgny >= 0 ) {
;; if( sgnx < 0 ) {
;; x += Pi;
;; }
;; } else {
;; if( sgnx > 0 ) {
;; x -= Pi;
;; }
;; }
;; }
;; return( x );
;; }
;;
;; input:
;; EAX - pointer to Y
;; EDX - pointer to X
;; EBX - pointer to result
;;
defp __fpatan
push EDI ; save registers
push ESI ; ...
push ECX ; ...
mov EDI,EAX ; save address of y
mov CX,8[EDI] ; get sgn(y)
_guess ; guess: y == 0
shl CX,1 ; - get rid of sign bit
_quif ne ; - quit if y != 0
test byte ptr 9[EDX],80h ; - if x < 0.0
_if ne ; - then
mov word ptr 8[EBX],PI_EXP; - - return pi
mov dword ptr 4[EBX],PI_HW; - - ...
mov dword ptr [EBX],PI_LW; - - ...
_else ; - else
mov word ptr 8[EBX],0 ; - - return 0.0
mov dword ptr 4[EBX],0 ; - - ...
mov dword ptr [EBX],0 ; - - ...
_endif ; - endif
_admit ; guess: x == 0
mov CX,8[EDX] ; - get sgn(x)
shl CX,1 ; - quit if x != 0
_quif ne ; - ...
mov AX,8[EDI] ; - get sign of y
and AX,8000h ; - ...
or AX,PIBY2_EXP ; - return (+/-) pi/2
mov word ptr 8[EBX],AX ; - ...
mov dword ptr 4[EBX],PI_HW ; - ...
mov dword ptr [EBX],PI_LW ; - ...
_admit ; admit: calc. arctan( y / x )
mov CH,9[EDI] ; - save sign of y
call __FLDD ; - calc. result = y/x
mov EAX,EBX ; - point to argument
call __atan ; - calc. atan(y/x)
mov DL,9[EBX] ; - get sign of result
or CH,CH ; - quit if y < 0.0
_quif s ; - ...
or DL,DL ; - if result < 0
_if s ; - then
mov EAX,EBX ; - - calc. x += pi
push PI_EXP ; - - ...
push PI_HW ; - - ...
push PI_LW ; - - ...
call __FLDAC ; - - ...
_endif ; - endif
_admit ; admit: y < 0.0
or DL,DL ; - if result > 0
_if g ; - then
mov EAX,EBX ; - - calc. x -= pi
push 8000h+PI_EXP ; - - ...
push PI_HW ; - - ...
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?