"robert bristow-johnson" <rbj@surfglobal.net> wrote in message
news:BB4E0ED6.28F8%rbj@surfglobal.net...
(snip)
> i wonder how a standard C or Fortran (blech) math library does arctan()?
> has anyone got some code for that? do they just split it into |x|<1 and
> |x|>1 regions and run one of the two converging series on that?
Here is the IBM OS/360 Fortran library DATAN function.
The comments explain argument reduction.
LATN TITLE 'ARCTANGENT FUNCTION (LONG)'
00900018
IHCLATAN CSECT
01800018
* ARCTANGENT FUNCTION (LONG)
02700018
* 1. REDUCE THE CASE TO THE 1ST OCTANT BY USING
03600018
* ATAN(-X) = -ATAN(X), ATAN(1/X) = PI/2-ATAN(X).
04500018
* 2. REDUCE FURTHER TO THE CASE /X/ LESS THAN TAN(PI/12)
05400018
* BY ATAN(X) PI/6+ATAN((X*SQRT3-1)/(X+SQRT3)).
06300018
* 3. FOR THE BASIC RANGE (X LESS THAN TAN(PI/12)), USE
07200018
* A FRACTIONAL APPROXIMATION.
08100018
SPACE
09000018
ENTRY DATAN
09900018
SPACE
10800018
GRA EQU 1 ARGUMENT POINTER
11700018
GRS EQU 13 SAVE AREA POINTER
12600018
GRR EQU 14 RETURN REGISTER
13500018
GRL EQU 15 LINK REGISTER
14400018
GR0 EQU 0 SCRATCH REGISTERS
15300018
GR1 EQU 1
16200018
GR2 EQU 14
17100018
FR0 EQU 0 ANSWER REGISTER
18000018
FR2 EQU 2 SCRATCH REGISTERS
18900018
FR4 EQU 4
19800018
FR6 EQU 6
20700018
SPACE
21600018
USING *,GRL
22500018
DATAN BC 15,LATAN
23400018
DC AL1(5)
24300018
DC CL5'DATAN'
25200018
SPACE
26100018
LATAN STM GRR,GRL,12(GRS) SAVE REGISTERS
27000018
L GR1,0(GRA)
27900018
LD FR0,0(GR1) OBTAIN ARGUMENT
28800018
L GR0,0(GR1) SAVE ARG FOR SIGN CONTROL
29700018
LPER FR0,FR0 AND SET SIGN POSITIVE
30600018
LD FR4,ONE
31500018
SR GR1,GR1 GR1, GR2 FOR DISTINGUISHING CASES
32400018
LA GR2,ZERO
33300018
CER FR0,FR4
34200018
BC 12,SKIP1
35100018
LDR FR2,FR4 IF X GREATER THAN 1, TAKE INVERSE
36000018
DDR FR2,FR0 AND INCREMEMENT GR1 BY 16
36900018
LDR FR0,FR2
37800018
LA GR1,16
38700018
SPACE
39600018
SKIP1 CE FR0,SMALL IF ARG LESS THAN 16**-7, ANS=ARG.
40500018
BC 12,READY THIS AVOIDS UNDERFLOW EXCEPTION
41400018
CE FR0,TAN15
42300018
BC 12,SKIP2
43200018
LDR FR2,FR0 IF X GREATER THAN TAN(PI/12),
44100018
MD FR0,RT3M1 REDUCE X TO (X*SQRT3-1)/(X+SQRT3)
45000018
SDR FR0,FR4 COMPUTE X*SQRT3-1 AS
45900018
ADR FR0,FR2 X*(SQRT3-1)-1+X
46800018
AD FR2,RT3 TO GAIN ACCURACY
47700018
DDR FR0,FR2
48600018
LA GR2,8(GR2) INCREMENT GR2 BY 8
49500018
SPACE
50400018
SKIP2 LDR FR6,FR0 COMPUTE ATAN OF REDUCED ARGUMENT BY
51300018
MDR FR0,FR0 ATAN(X) = X+X*X**2*F, WHERE
52200018
LD FR4,C7 F = C1+C2/(X**2+C3+C4/
53100018
ADR FR4,FR0 (X**2+C5+C6/(X**2+C7)))
54000018
LD FR2,C6
54900018
DDR FR2,FR4
55800018
AD FR2,C5
56700018
ADR FR2,FR0
57600018
LD FR4,C4
58500018
DDR FR4,FR2
59400018
AD FR4,C3
60300018
ADR FR4,FR0
61200018
LD FR2,C2
62100018
DDR FR2,FR4
63000018
AD FR2,C1
63900018
MDR FR0,FR2
64800018
MDR FR0,FR6
65700018
ADR FR0,FR6
66600018
SPACE
67500018
READY AD FR0,0(GR1,GR2) DEPENDING ON THE CASE,
68400018
LNR GR1,GR1 EITHER ADD 0 OR PI/6, OR
69300018
SD FR0,ZERO(GR1) SUBTRACT FROM PI/3 OR PI/2
70200018
LPER FR0,FR0
71100018
LTR GR0,GR0 DO THE LATTER IN TWO STEPS
72000018
BC 10,*+6 IF SIGN WAS NEGATIVE,
72900018
LNER FR0,FR0 ANSWER IS NEGATIVE
73800018
SPACE
74700018
EXIT L GRR,12(GRS)
75600018
MVI 12(GRS),X'FF'
76500018
BCR 15,GRR RETURN
77400018
SPACE
78300018
DS 0F
79200018
SMALL DC X'3A100000'
80100018
DS 0D
81000018
C1 DC X'BF1E31FF1784B965' -0.7371899082768562E-2
81900018
C2 DC X'C0ACDB34C0D1B35D' -0.6752198191404210
82800018
C3 DC X'412B7CE45AF5C165' 0.2717991214096480E+1
83700018
C4 DC X'C11A8F923B178C78' -0.1660051565960002E+1
84600018
C5 DC X'412AB4FD5D433FF6' 0.2669186939532663E+1
85500018
C6 DC X'C02298BB68CFD869' -0.1351430064094942
86400018
C7 DC X'41154CEE8B70CA99' 0.1331282181443987E+1
87300018
RT3M1 DC X'40BB67AE8584CAA8' SQRT(3)-1
88200018
ONE DC X'4110000000000000' THESE
89100018
RT3 DC X'411BB67AE8584CAB' SQRT(3) SIX
90000018
ZERO DC D'0' 0 CONSTANTS
90900018
DC X'40860A91C16B9B2C' PI/6 MUST
91800018
DC X'C0921FB54442D184' -PI/2+1 BE
92700018
DC X'BFC152382D736574' -(PI/3-F)+1 CONSECUTIVE
93600018
TAN15 DC X'40449851'
94500018
END
95400018