(FILECREATED "24-Jun-86 20:37:56" {ERIS}<LISPCORE>LIBRARY>CMLFLOAT.;30 71481        changes to:  (FNS %%ATAN1 %%ATAN-FLOAT \FLOAT TRUNCATE %%COMPLEX-ABS COMPLEX CL:SQRT                         %%SQRT-PERFECT %%SQRT-RATIO-PERFECT CL:SIN CL:COS %%OLD-TAN-FLOAT ASIN                         %%OLD-ASIN-FLOAT ACOS)                   (VARS CMLFLOATCOMS CMLFLOATJUNKCOMS)      previous date: "30-May-86 16:51:42" {ERIS}<LISPCORE>LIBRARY>CMLFLOAT.;27)(* Copyright (c) 1986 by Xerox Corporation. All rights reserved.)(PRETTYCOMPRINT CMLFLOATCOMS)(RPAQQ CMLFLOATCOMS        ((* * CMLFLOAT -- Covering sections 12.5-12.5.3 irrational, transcendental, exponential,            logarithmic, trigonometric, and hyperbolic functions. -- By Kelly Roach. *)        (COMS (* LLFLOAT addition. *)              (FNS %%FLOAT %%MAKE-ARRAY))        (COMS * CMLFLOATJUNKCOMS)        (COMS (* Constants. *)              (CONSTANTS (PI (%%FLOAT 16457 4059))))        (COMS (* CMLARITH improvements. Put these back in CMLARITH when Larry gets finished. *)              (* PHASE and TRUNCATE had bugs I missed before handing off to Larry. %%COMPLEX-ABS                  changes because CL:SQRT is smarter now and also %%COMPLEX-ABS was calling SQRT                  instead of CL:SQRT. COMPLEX has been fixed so that (COMPLEX 0.0 0.0)                 = 0.0 \FLOAT has been upgraded so that (FLOAT (COMPLEX 2 3))                 =                 (COMPLEX 2.0 3.0)                 *)              (FNS PHASE TRUNCATE %%COMPLEX-ABS COMPLEX \FLOAT)              (P (printout T                         "Warning: CMLFLOAT redefined some CMLARITH functions that need to be fixed."                         T)))        (COMS (* EXP *)              (COMS * CMLFLOATEXPCOMS)              (FNS EXP %%EXP-FLOAT %%EXP-COMPLEX))        (COMS (* EXPT *)              (FNS CL:EXPT %%EXPT-INTEGER %%EXPT-FLOAT %%EXPT-COMPLEX %%EXPT-COMPLEX-POWER))        (COMS (* LOG *)              (COMS * CMLFLOATLOGCOMS)              (FNS CL:LOG %%LOG-FLOAT %%LOG-COMPLEX %%OLD-LOG-FLOAT))        (COMS (* SQRT *)              (FNS CL:SQRT %%SQRT-PERFECT %%SQRT-INTEGER %%SQRT-INTEGER-PERFECT %%SQRT-FLOAT                    %%SQRT-RATIO %%SQRT-RATIO-PERFECT %%SQRT-COMPLEX %%SQRT-COMPLEX-PERFECT                    %%OLD-SQRT-COMPLEX)              (FNS ISQRT))        (DECLARE: EVAL@COMPILE DONTCOPY (CONSTANTS (%%2PI (%%FLOAT 16585 4059))                                               (%%PI (%%FLOAT 16457 4059))                                               (%%PI/2 (%%FLOAT 16329 4059))                                               (%%-PI/2 (%%FLOAT 49097 4059))                                               (%%PI/4 (%%FLOAT 16201 4059))                                               (%%-PI/4 (%%FLOAT 48969 4059))                                               (SIXTH-PI .5236)                                               (%%2/PI (%%FLOAT 16162 63875))))        (COMS (* SIN *)              (COMS * CMLFLOATSINCOMS)              (FNS CL:SIN %%SIN-FLOAT %%SIN-COMPLEX))        (COMS (* COS *)              (FNS CL:COS %%COS-COMPLEX))        (COMS (* TAN *)              (COMS * CMLFLOATTANCOMS)              (FNS CL:TAN %%TAN-FLOAT %%TAN-COMPLEX))        (COMS (* ASIN *)              (COMS * CMLFLOATASINCOMS)              (FNS ASIN %%ASIN-FLOAT %%ASIN-COMPLEX))        (COMS (* ACOS *)              (FNS ACOS %%ACOS-COMPLEX))        (COMS (* ATAN *)              (FNS CL:ATAN %%ATAN1 %%ATAN2 %%ATAN-DOMAIN-CHECK %%ATAN-FLOAT %%ATAN-COMPLEX))        (COMS (* CIS *)              (FNS CIS))        (COMS (* SINH COSH TANH *)              (FNS SINH COSH TANH))        (COMS (* ASINH ACOSH ATANH *)              (FNS ASINH ACOSH ATANH %%ATANH-DOMAIN-CHECK))        (DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS               (ADDVARS (NLAMA)                      (NLAML)                      (LAMA %%ATANH-DOMAIN-CHECK ATANH ACOSH ASINH TANH COSH SINH CIS %%ATAN-COMPLEX                             %%ATAN-FLOAT %%ATAN-DOMAIN-CHECK %%ATAN2 %%ATAN1 CL:ATAN %%ACOS-COMPLEX                             ACOS %%ASIN-COMPLEX ASIN %%TAN-COMPLEX CL:TAN %%COS-COMPLEX CL:COS                             %%SIN-COMPLEX CL:SIN ISQRT %%OLD-SQRT-COMPLEX %%SQRT-PERFECT CL:SQRT                             %%LOG-COMPLEX CL:LOG %%EXPT-COMPLEX-POWER %%EXPT-COMPLEX %%EXPT-INTEGER                             CL:EXPT %%EXP-COMPLEX %%EXP-FLOAT EXP COMPLEX %%COMPLEX-ABS TRUNCATE                             PHASE)))))(* * CMLFLOAT -- Covering sections 12.5-12.5.3 irrational, transcendental, exponential, logarithmic, trigonometric, and hyperbolic functions. -- By Kelly Roach. *)(* LLFLOAT addition. *)(DEFINEQ(%%FLOAT  (LAMBDA (HIWORD LOWORD)                                    (* kbr: "14-May-86 16:43")    (\FLOATBOX (\VAG2 HIWORD LOWORD))))(%%MAKE-ARRAY  (LAMBDA (LIST)                                             (* kbr: "15-May-86 18:09")                                                             (* Function to build Interlisp arrays.                                                             I would prefer to build Common Lisp                                                              arrays, but I don't think POLYEVAL                                                              opcode will understand them.                                                             *)    (PROG (ARRAY)          (SETQ ARRAY (ARRAY (LENGTH LIST)                             (QUOTE FLOATP)                             0.0 0))          (for ELEMENT in LIST as I from 0 do (SETA ARRAY I ELEMENT))          (RETURN ARRAY)))))(RPAQQ CMLFLOATJUNKCOMS ((DECLARE: EVAL@COMPILE DONTCOPY (CONSTANTS (%%SINGLE-FLOAT-EXPONENT-LENGTH                                                                     8)                                                                (%%SINGLE-FLOAT-MANTISSA-LENGTH                                                                 23)                                                                (%%FLOAT-ONE 1.0)                                                                (%%FLOAT-HALF .5)                                                                (%%SQRT-HALF (%%FLOAT 16181 1267))                                                                (%%E (%%FLOAT 16429 63530))                                                                (SQRT3 1.730525)                                                                (2-SQRT3 .2679482)                                                                (INV-2-SQRT3 3.732071)                                                                (%%FLOAT-HALF .5)                                                                (%%ZERO 0.0)))))(DECLARE: EVAL@COMPILE DONTCOPY (DECLARE: EVAL@COMPILE (RPAQQ %%SINGLE-FLOAT-EXPONENT-LENGTH 8)(RPAQQ %%SINGLE-FLOAT-MANTISSA-LENGTH 23)(RPAQQ %%FLOAT-ONE 1.0)(RPAQQ %%FLOAT-HALF .5)(RPAQ %%SQRT-HALF (%%FLOAT 16181 1267))(RPAQ %%E (%%FLOAT 16429 63530))(RPAQQ SQRT3 1.730525)(RPAQQ 2-SQRT3 .2679482)(RPAQQ INV-2-SQRT3 3.732071)(RPAQQ %%FLOAT-HALF .5)(RPAQQ %%ZERO 0.0)(CONSTANTS (%%SINGLE-FLOAT-EXPONENT-LENGTH 8)       (%%SINGLE-FLOAT-MANTISSA-LENGTH 23)       (%%FLOAT-ONE 1.0)       (%%FLOAT-HALF .5)       (%%SQRT-HALF (%%FLOAT 16181 1267))       (%%E (%%FLOAT 16429 63530))       (SQRT3 1.730525)       (2-SQRT3 .2679482)       (INV-2-SQRT3 3.732071)       (%%FLOAT-HALF .5)       (%%ZERO 0.0))))(* Constants. *)(DECLARE: EVAL@COMPILE (RPAQ PI (%%FLOAT 16457 4059))(CONSTANTS (PI (%%FLOAT 16457 4059))))(* CMLARITH improvements. Put these back in CMLARITH when Larry gets finished. *)(* PHASE and TRUNCATE had bugs I missed before handing off to Larry. %%COMPLEX-ABS changes because CL:SQRT is smarter now and also %%COMPLEX-ABS was calling SQRT instead of CL:SQRT. COMPLEX has been fixed so that (COMPLEX 0.0 0.0) = 0.0 \FLOAT has been upgraded so that (FLOAT (COMPLEX 2 3)) = (COMPLEX 2.0 3.0) *)(DEFINEQ(PHASE  (CL:LAMBDA (NUMBER)                                        (* kbr: "14-May-86 11:26")                                                             (* Returns the angle part of the polar                                                              representation of NUMBER *)         (COND            ((COMPLEXP NUMBER)             (CL:ATAN (IMAGPART NUMBER)                    (REALPART NUMBER)))            ((MINUSP NUMBER)             %%PI)            (T 0))))(TRUNCATE  (CL:LAMBDA (NUMBER &OPTIONAL (DIVISOR 1))                  (* kbr: "24-Jun-86 19:30")                                                             (* Returns number (or number/divisor)                                                              as an integer, rounded toward 0.0 The                                                              second returned value is the                                                              remainder. *)         (PROG (TRU REM)               (SETQ TRU (COND                            ((EQ DIVISOR 1)                             (TYPECASE NUMBER (INTEGER NUMBER)                                    (FLOAT (\FIXP.FROM.FLOATP NUMBER))                                    (RATIO (IQUOTIENT (RATIO-NUMERATOR NUMBER)                                                  (RATIO-DENOMINATOR NUMBER)))                                    (T (LISPERROR "ILLEGAL ARG" NUMBER))))                            (T (TYPECASE NUMBER (INTEGER (TYPECASE DIVISOR (INTEGER (IQUOTIENT NUMBER                                                                                            DIVISOR))                                                                (FLOAT (FQUOTIENT NUMBER DIVISOR))                                                                (RATIO (RETURN (TRUNCATE (/ NUMBER                                                                                             DIVISOR))                                                                              ))                                                                (T (LISPERROR "ILLEGAL ARG" DIVISOR))                                                                ))                                      (FLOAT (TYPECASE DIVISOR ((OR INTEGER FLOAT)                                                                (\FIXP.FROM.FLOATP (FQUOTIENT NUMBER                                                                                           DIVISOR)))                                                    (RATIO (RETURN (TRUNCATE (/ NUMBER DIVISOR))))                                                    (T (LISPERROR "ILLEGAL ARG" DIVISOR))))                                      (RATIO (RETURN (TRUNCATE (/ NUMBER DIVISOR))))                                      (T (LISPERROR "ILLEGAL ARG" NUMBER))))))               (SETQ REM (- NUMBER (CL:* TRU DIVISOR)))               (RETURN (VALUES TRU REM)))))(%%COMPLEX-ABS  (CL:LAMBDA (Z)                                             (* kbr: "24-Jun-86 19:09")                                                             (* Magnitude of a complex number *)         (PROG (X Y R A)               (SETQ X (COMPLEX-REALPART Z))               (SETQ Y (COMPLEX-IMAGPART Z))               (SETQ R (+ (CL:* X X)                          (CL:* Y Y)))               (SETQ A (CL:SQRT R))               (RETURN A))))(COMPLEX  (CL:LAMBDA (REALPART &OPTIONAL (IMAGPART 0))               (* kbr: "29-May-86 20:17")                                                             (* Builds a complex number from the                                                              specified components.                                                             *)                                                             (* TBW: Bug in TYPECASE? Had to change                                                              RATIO to (OR INTEGER RATIO) in two                                                              places. *)         (CL:IF (= IMAGPART 0)                (TYPECASE IMAGPART ((OR INTEGER RATIO)                                    REALPART)                       (FLOAT (FLOAT REALPART))                       (T (LISPERROR "ILLEGAL ARG" IMAGPART)))                (TYPECASE REALPART ((OR INTEGER RATIO)                                    (TYPECASE IMAGPART ((OR INTEGER RATIO)                                                        (%%MAKE-COMPLEX REALPART IMAGPART))                                           (FLOAT (%%MAKE-COMPLEX (FLOAT REALPART)                                                         IMAGPART))                                           (T (LISPERROR "ILLEGAL ARG" IMAGPART))))                       (FLOAT (%%MAKE-COMPLEX REALPART (FLOAT IMAGPART)))                       (T (LISPERROR "ILLEGAL ARG" REALPART))))))(\FLOAT  (LAMBDA (X)                                                (* kbr: "24-Jun-86 20:13")    (OR (FLOATP X)        (TYPECASE X (INTEGER                     (SELECTC (NTYPX X)                         (\FIXP (LET ((HI (fetch (FIXP HINUM) of X))                                      (LO (fetch (FIXP LONUM) of X))                                      (SIGN 0))                                     (COND                                        ((IGREATERP HI MAX.POS.HINUM)                                         (.NEGATE. HI LO)                                         (SETQ SIGN 1)))                                     (\MAKEFLOAT SIGN (IPLUS \EXPONENT.BIAS 31)                                            HI LO T)))                         (\SMALLP (LET* ((HI 0)                                         (SIGN 0)                                         (LO (COND                                                ((IGEQ X 0)                                                 X)                                                (T (SETQ SIGN 1)                                                             (* X is negative--negate it)                                                   (COND                                                      ((EQ 0 (\LOLOC X))                                                             (* Min small integer)                                                       (SETQ HI 1)                                                       0)                                                      (T (ADD1 (IDIFFERENCE MAX.SMALL.INTEGER                                                                      (\LOLOC X)))))))))                                        (\MAKEFLOAT SIGN (IPLUS \EXPONENT.BIAS 31)                                               HI LO T)))                         (\BIGNUM.TO.FLOAT X)))               (RATIO (FQUOTIENT (RATIO-NUMERATOR X)                             (RATIO-DENOMINATOR X)))               (COMPLEX (%%MAKE-COMPLEX (\FLOAT (REALPART X))                               (\FLOAT (IMAGPART X))))               (T (\FLOAT (LISPERROR "NON-NUMERIC ARG" X T))))))))(printout T "Warning: CMLFLOAT redefined some CMLARITH functions that need to be fixed." T)(* EXP *)(RPAQQ CMLFLOATEXPCOMS ((CONSTANTS (%%LOG-BASE2-E (%%FLOAT 16312 43579)))                        (* * %%EXP-POLY contains P and Q coefficients of Harris et al EXPB 1103                            rational approximation to (EXPT 2 X)                           in interval (0 .125)                           %. %%EXP-TABLE contains values of powers (EXPT 2 (/ N 8)) . *)                        (INITVARS (%%EXP-POLY (%%MAKE-ARRAY (LIST (%%FLOAT 15549 17659)                                                                  (%%FLOAT 16256 0)                                                                  (%%FLOAT 16801 38273)                                                                  (%%FLOAT 17257 7717)                                                                  (%%FLOAT 17597 11739)                                                                  (%%FLOAT 17800 30401))))                               (%%EXP-TABLE (%%MAKE-ARRAY (LIST (%%FLOAT 16256 0)                                                                (%%FLOAT 16267 38338)                                                                (%%FLOAT 16280 14320)                                                                (%%FLOAT 16293 65239)                                                                (%%FLOAT 16309 1267)                                                                (%%FLOAT 16325 26410)                                                                (%%FLOAT 16343 17661)                                                                (%%FLOAT 16362 49351)))))))(DECLARE: EVAL@COMPILE (RPAQ %%LOG-BASE2-E (%%FLOAT 16312 43579))(CONSTANTS (%%LOG-BASE2-E (%%FLOAT 16312 43579))))(* * %%EXP-POLY contains P and Q coefficients of Harris et al EXPB 1103 rational approximation to (EXPT 2 X) in interval (0 .125) %. %%EXP-TABLE contains values of powers (EXPT 2 (/ N 8)) . *)(RPAQ? %%EXP-POLY (%%MAKE-ARRAY (LIST (%%FLOAT 15549 17659)                                      (%%FLOAT 16256 0)                                      (%%FLOAT 16801 38273)                                      (%%FLOAT 17257 7717)                                      (%%FLOAT 17597 11739)                                      (%%FLOAT 17800 30401))))(RPAQ? %%EXP-TABLE (%%MAKE-ARRAY (LIST (%%FLOAT 16256 0)                                       (%%FLOAT 16267 38338)                                       (%%FLOAT 16280 14320)                                       (%%FLOAT 16293 65239)                                       (%%FLOAT 16309 1267)                                       (%%FLOAT 16325 26410)                                       (%%FLOAT 16343 17661)                                       (%%FLOAT 16362 49351))))(DEFINEQ(EXP  (CL:LAMBDA (NUMBER)                                        (* kbr: "28-May-86 15:09")                                                             (* Calculates e to the given power,                                                              where e is the base of natural                                                              logarithms. *)         (TYPECASE NUMBER (COMPLEX (%%EXP-COMPLEX NUMBER))                (NUMBER (%%EXP-FLOAT (FLOAT NUMBER)))                (T (LISPERROR "NON-NUMERIC ARG" NUMBER)))))(%%EXP-FLOAT  (CL:LAMBDA (X)                                             (* kbr: "30-May-86 15:50")                    (* * (EXP X) for float X calculated via EXPB 1103 rational approximation of           Harris et al. *)         (PROG (M N R ANSWER)               (DECLARE (GLOBALVARS %%EXP-TABLE %%EXP-POLY))                    (* * First, the problem of (EXP X) is converted into a problem          (EXPT 2 Y) where Y = (CL:* %%LOG-BASE2-E X)%.          Then range reduction is accomplished via          (EXPT 2 Y) = (CL:* (EXPT 2 M) (EXPT 2 (/ N 8))          (EXPT 2 R)) where M and N are integers and R is a float in the interval          (0.0 .125) After M N R are determined, (EXPT 2 M) is effected by scaling,          (EXPT 2 (/ N 8)) is found by table lookup, and          (EXPT 2 R) is calculated by rational approximation EXPB 1103 of Harris et al.          *)               (MULTIPLE-VALUE-SETQ (M R)                      (CL:FLOOR (CL:* %%LOG-BASE2-E X)))               (MULTIPLE-VALUE-SETQ (N R)                      (CL:FLOOR R .125))               (SETQ ANSWER (SCALE-FLOAT (CL:* (ELT %%EXP-TABLE N)                                               (/ (POLYEVAL R %%EXP-POLY 5)                                                  (POLYEVAL (- R)                                                         %%EXP-POLY 5)))                                   M))               (RETURN ANSWER))))(%%EXP-COMPLEX  (CL:LAMBDA (Z)                                             (* compute exp (z) where z is complex                                                              is called by exp *)         (LET* ((X (REALPART Z))                (Y (IMAGPART Z)))               (CL:* (EXP X)                     (CIS Y))))))(* EXPT *)(DEFINEQ(CL:EXPT  (CL:LAMBDA (X N)                                           (* kbr: "28-May-86 15:12")                    (* This function calculates X raised to the nth power.          It separates the cases by the type of N for efficiency reasons, as powers can           be calculated more efficiently if N is a positive integer, Therefore, All           integer values of N are calculated as positive integers, and inverted if           negative. *)         (COND            ((AND (RATIONALP X)                  (INTEGERP N))             (%%EXPT-INTEGER X N))            ((ZEROP X)             (CL:IF (PLUSP N)                    X                    (CL:ERROR "~A to a non-positive power ~A." X N)))            ((AND (COMPLEXP X)                  (INTEGERP N))             (%%EXPT-INTEGER X N))            ((COMPLEXP N)             (CL:IF (OR (COMPLEXP X)                        (PLUSP X))                    (%%EXPT-COMPLEX-POWER X N)                    (CL:ERROR "~A negative number to a complex power ~A." X N)))            ((COMPLEXP X)             (%%EXPT-COMPLEX X N))            ((AND (NOT (INTEGERP N))                  (MINUSP X))             (CL:ERROR "Negative number ~A to non-integral power ~A." X N))            (T (%%EXPT-FLOAT (FLOAT X)                      (FLOAT N))))))(%%EXPT-INTEGER  (CL:LAMBDA (BASE POWER)                                    (* kbr: "28-May-86 15:58")                    (* * (EXPT BASE POWER) where POWER is an integer.          *)         (COND            ((MINUSP POWER)             (/ (%%EXPT-INTEGER BASE (- POWER))))            ((AND (RATIONALP BASE)                  (NOT (INTEGERP BASE)))             (%%MAKE-RATIO (%%EXPT-INTEGER (NUMERATOR BASE)                                  POWER)                    (%%EXPT-INTEGER (DENOMINATOR BASE)                           POWER)))            ((AND (INTEGERP BASE)                  (= BASE 2))             (ASH 1 POWER))            (T (CL:DO ((NEXTN (ASH POWER -1)                              (ASH POWER -1))                       (TOTAL (CL:IF (ODDP POWER)                                     BASE 1)                              (CL:IF (ODDP POWER)                                     (CL:* BASE TOTAL)                                     TOTAL)))                      ((ZEROP NEXTN)                       TOTAL)                      (SETQ BASE (CL:* BASE BASE))                      (SETQ POWER NEXTN))))))(%%EXPT-FLOAT  (LAMBDA (X Y)                                              (* kbr: "29-May-86 00:03")                    (* * (EXPT X Y) where X is a nonnegative float and Y is a float.          *)    (COND       ((= X 0.0)        0.0)       (T (EXP (CL:* Y (CL:LOG X)))))))(%%EXPT-COMPLEX  (CL:LAMBDA (Z N)                                           (* compute (complex) ^n where n is an                                                              integer some round-off error if n is                                                              not a fixnum *)         (CL:* (CL:EXPT (%%COMPLEX-ABS Z)                      N)               (CIS (CL:* N (PHASE Z))))))(%%EXPT-COMPLEX-POWER  (CL:LAMBDA (Z W)                                           (* this function computes z ^ w where                                                              w is a complex number it can also be                                                              used for any positive real number.                                                             *)         (EXP (CL:* W (CL:LOG Z))))))(* LOG *)(RPAQQ CMLFLOATLOGCOMS ((DECLARE: EVAL@COMPILE DONTCOPY (CONSTANTS (%%LOG2 (%%FLOAT 16177 29208))                                                               (%%SQRT2 (%%FLOAT 16309 1267))))                        (* * %%LOG-PPOLY and %%LOG-QPOLY contain P and Q coefficients of Harris et al                            LOGE 2707 rational approximation to (LOG X)                           in interval ((SQRT .5)                                        (SQRT 2)) . *)                        (INITVARS (%%LOG-PPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 16042 22803)                                                                   (%%FLOAT 49484 23590)                                                                   (%%FLOAT 17044 17982)                                                                   (%%FLOAT 49926 37153)                                                                   (%%FLOAT 17046 5367))))                               (%%LOG-QPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 16256 0)                                                                (%%FLOAT 49512 9103)                                                                (%%FLOAT 16992 42274)                                                                (%%FLOAT 49823 38048)                                                                (%%FLOAT 16918 5367)))))))(DECLARE: EVAL@COMPILE DONTCOPY (DECLARE: EVAL@COMPILE (RPAQ %%LOG2 (%%FLOAT 16177 29208))(RPAQ %%SQRT2 (%%FLOAT 16309 1267))(CONSTANTS (%%LOG2 (%%FLOAT 16177 29208))       (%%SQRT2 (%%FLOAT 16309 1267)))))(* * %%LOG-PPOLY and %%LOG-QPOLY contain P and Q coefficients of Harris et al LOGE 2707 rational approximation to (LOG X) in interval ((SQRT .5) (SQRT 2)) . *)(RPAQ? %%LOG-PPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 16042 22803)                                       (%%FLOAT 49484 23590)                                       (%%FLOAT 17044 17982)                                       (%%FLOAT 49926 37153)                                       (%%FLOAT 17046 5367))))(RPAQ? %%LOG-QPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 16256 0)                                       (%%FLOAT 49512 9103)                                       (%%FLOAT 16992 42274)                                       (%%FLOAT 49823 38048)                                       (%%FLOAT 16918 5367))))(DEFINEQ(CL:LOG  (CL:LAMBDA (NUMBER &OPTIONAL (BASE NIL BASE-SUPPLIED))     (* kbr: "30-May-86 00:19")         (COND            (BASE-SUPPLIED (/ (CL:LOG NUMBER)                              (CL:LOG BASE)))            (T (TYPECASE NUMBER (COMPLEX (%%LOG-COMPLEX NUMBER))                      (NUMBER (CL:IF (MINUSP NUMBER)                                     (COMPLEX (%%LOG-FLOAT (FLOAT (- NUMBER)))                                            %%PI)                                     (%%LOG-FLOAT (FLOAT NUMBER))))                      (T (LISPERROR "NON-NUMERIC ARG" NUMBER)))))))(%%LOG-FLOAT  (LAMBDA (X)                                                (* kbr: "30-May-86 00:04")                    (* * (EXP X) for float X calculated via EXPB 1103 rational approximation of           Harris et al. *)                    (* * (LOG X) for nonnegative float X. *)    (PROG (R EXP Z Z2 ANSWER)          (DECLARE (GLOBALVARS %%LOG-PPOLY %%LOG-QPOLY))                    (* * NOTE: Probably best not to declare type of variables inside this routine           for now. I've found that FLOATP smashing combined with FLOATP declarations           compiles wrong. *)          (COND             ((NOT (FGREATERP X 0.0))              (ERROR "LOG OF ZERO:" X)))                    (* * Range reduce to an R in interval ((SQRT .5)          (SQRT 2)) via identity (LOG X) = (+ (LOG R)          (CL:* %%LOG-2 EXP)) for a suitable integer EXP.          This reduction depends on and smashes the FLOATP representation of R.          *)          (SETQ R (\FLOAT.BOX X))          (SETQ EXP (- (fetch (FLOATP EXPONENT) of R)                       \EXPONENT.BIAS))          (replace (FLOATP EXPONENT) of R with \EXPONENT.BIAS)          (COND             ((> R %%SQRT2)              (SETQ EXP (1+ EXP))              (SETQ R (/ R 2.0))))                    (* * (LOG R) is calculated by rational approximation LOGE 2707 of Harris et al.          *)          (SETQ Z (/ (1- R)                     (1+ R)))          (SETQ Z2 (CL:* Z Z))          (SETQ ANSWER (+ (CL:* Z (/ (POLYEVAL Z2 %%LOG-PPOLY 4)                                     (POLYEVAL Z2 %%LOG-QPOLY 4)))                          (CL:* %%LOG2 EXP)))          (RETURN ANSWER))))(%%LOG-COMPLEX  (CL:LAMBDA (Z)                                             (* natural log of a complex number *)         (COMPLEX (CL:LOG (%%COMPLEX-ABS Z))                (PHASE Z))))(%%OLD-LOG-FLOAT  (LAMBDA (X)                                                (* kbr: "29-May-86 00:02")                    (* * (LOG X) for nonnegative float X. *)    (PROG (SX EXP SSUM)          (DECLARE (GLOBALVARS \LOGARRAY))          (COND             ((NOT (FGREATERP X 0.0))              (ERROR "LOG OF ZERO:" X)))          (SETQ SX (\FLOAT.BOX X))          (SETQ EXP (IDIFFERENCE (fetch (FLOATP EXPONENT) of SX)                           \EXPONENT.BIAS))                    (* * Depends on Interlisp-D's use of IEEE 32 bit float format internally and           smashes the number to the range 1 to 2 and saves the exponent)          (replace (FLOATP EXPONENT) of SX with \EXPONENT.BIAS)          (SETQ SX (FDIFFERENCE SX 1.0))          (SETQ SSUM (POLYEVAL SX \LOGARRAY 8))                    (* * Polynomial from Handbook of Mathematical Functions          (edited by Aramowitz) page 69 accuracy 28 bits          (of the 24 available!))          (RETURN (FPLUS SSUM (FTIMES %%LOG-2 EXP)))))))(* SQRT *)(DEFINEQ(CL:SQRT  (CL:LAMBDA (X)                                             (* kbr: "29-May-86 16:35")         (CL:IF (AND (NOT (COMPLEXP X))                     (MINUSP X))                (COMPLEX 0 (CL:SQRT (ABS X)))                (TYPECASE X (INTEGER (%%SQRT-INTEGER X))                       (FLOAT (%%SQRT-FLOAT X))                       (RATIO (%%SQRT-RATIO X))                       (COMPLEX (%%SQRT-COMPLEX X))                       (T (LISPERROR "NON-NUMERIC ARG" X))))))(%%SQRT-PERFECT  (CL:LAMBDA (X)                                             (* kbr: "29-May-86 19:26")                    (* * Perfect (SQRT X)%. Returns square root of X if X is a perfect square of a           rational number (includes integers) or complex number with rational           coefficients and otherwise NIL. *)         (CL:IF (AND (NOT (COMPLEXP X))                     (MINUSP X))                (LET ((S (%%SQRT-PERFECT (ABS X))))                     (CL:IF S (COMPLEX 0 S)))                (TYPECASE X (INTEGER (%%SQRT-INTEGER-PERFECT X))                       (FLOAT NIL)                       (RATIO (%%SQRT-RATIO-PERFECT X))                       (COMPLEX (%%SQRT-COMPLEX-PERFECT X))                       (T (LISPERROR "NON-NUMERIC ARG" X))))))(%%SQRT-INTEGER  (LAMBDA (R)                                                (* kbr: "29-May-86 17:35")                    (* * (SQRT R) where R is a nonnegative integer.          *)                    (* * A little bit of cleverness to return a ratio if R is a perfect square.          Otherwise returns a float. *)    (OR (%%SQRT-INTEGER-PERFECT R)        (%%SQRT-FLOAT (FLOAT R)))))(%%SQRT-INTEGER-PERFECT  (LAMBDA (R)                                                (* kbr: "29-May-86 17:39")                    (* * Perfect (SQRT R) where R is a nonnegative integer.          If R is a perfect square, return square root of R, otherwise return NIL.          *)    (PROG (A)          (SETQ A (ISQRT R))          (COND             ((NOT (EQ (CL:* A A)                       R))              (RETURN NIL)))          (RETURN A))))(%%SQRT-FLOAT  (LAMBDA (X)                                                (* kbr: "29-May-86 20:32")                    (* * (SQRT X) for nonnegative float X. *)    (PROG (V)          (DECLARE (TYPE FLOATP X V))          (COND             ((NOT (FGREATERP X 0.0))                        (* Trichotomy ==> X = 0.0)              (RETURN 0.0)))          (SETQ V (create FLOATP                         EXPONENT _ (LOGAND (IPLUS \EXPONENT.BIAS                                                   (LRSH (LOGAND (IDIFFERENCE (fetch (FLOATP EXP)                                                                                 of X)                                                                        \EXPONENT.BIAS)                                                                (MASK.1'S 0 BITSPERWORD))                                                         1))                                           \MAX.EXPONENT)                         HIFRACTION _ (fetch (FLOATP HIFRAC) of X)))                    (* Exponent is stored as excess \EXPONENT.BIAS and although the LRSH doesn't           really do division by 2 (e.g., when the arg is negative) at least the low-order           8 bits will be right. It doesn't even matter that it may be off-by-one, due to           the infamous "Arithmetic Shifting Considered Harmful" since it is only an           estimate.)          (FRPTQ 4 (SETQ V (CL:* .5 (+ V (/ X V)))))          (RETURN V))))(%%SQRT-RATIO  (LAMBDA (R)                                                (* kbr: "29-May-86 17:41")                    (* * (SQRT R) where R is a nonnegative ratio.          *)                    (* * A little bit of cleverness to return a ratio if R is a perfect square.          Otherwise returns a float. *)    (OR (%%SQRT-RATIO-PERFECT R)        (%%SQRT-FLOAT (FLOAT R)))))(%%SQRT-RATIO-PERFECT  (LAMBDA (R)                                                (* kbr: "29-May-86 17:40")                    (* * Perfect (SQRT R) where R is a nonnegative ratio.          If R is a perfect square, return square root of R, otherwise NIL.          *)    (PROG (RNUM RDEN ANUM ADEN)                    (* * A little bit of cleverness to return a ratio if R is a perfect square.          Otherwise returns a float. *)          (SETQ RNUM (RATIO-NUMERATOR R))          (SETQ RDEN (RATIO-DENOMINATOR R))          (SETQ ANUM (%%SQRT-INTEGER-PERFECT RNUM))          (COND             ((NULL ANUM)              (RETURN NIL)))          (SETQ ADEN (%%SQRT-INTEGER-PERFECT RDEN))          (COND             ((NULL ADEN)              (RETURN NIL)))          (RETURN (%%MAKE-RATIO ANUM ADEN)))))(%%SQRT-COMPLEX  (LAMBDA (X)                                                (* kbr: "29-May-86 21:16")                    (* * (SQRT X) for complex X. *)    (PROG (ABS PHASE A B C D E ANSWER)          (DECLARE (TYPE FLOATP ABS PHASE A B C D E))          (SETQ ANSWER (%%SQRT-COMPLEX-PERFECT X))          (COND             (ANSWER (RETURN ANSWER)))          (SETQ A (FLOAT (REALPART X)))          (SETQ B (FLOAT (IMAGPART X)))                    (* * Make initial guess. *)          (SETQ ABS (CL:SQRT (ABS X)))          (SETQ PHASE (/ (PHASE X)                         2.0))          (SETQ C (CL:* ABS (CL:COS PHASE)))          (SETQ D (CL:* ABS (CL:SIN PHASE)))                    (* * Newton's method. *)          (for I from 1 to 4 do (SETQ E (+ (CL:* C C)                                           (CL:* D D)))                                (SETQ C (CL:* .5 (+ C (/ (+ (CL:* A C)                                                            (CL:* B D))                                                         E))))                                (SETQ D (CL:* .5 (+ D (/ (- (CL:* B C)                                                            (CL:* A D))                                                         E)))))          (SETQ ANSWER (COMPLEX C D))          (RETURN ANSWER))))(%%SQRT-COMPLEX-PERFECT  (LAMBDA (R)                                                (* kbr: "29-May-86 20:06")                    (* * Perfect (SQRT R) where R is a complex number.          If R is a perfect square, return square root of R, otherwise NIL.          *)    (PROG (A B M N DELTA)                    (* * First of all, let's say that R = M+iN.          *)          (SETQ M (REALPART R))          (COND             ((FLOATP M)              (RETURN NIL)))          (SETQ N (IMAGPART R))                    (* * If M is 0, then R is a pure imaginary and life is simple.          *)          (COND             ((= M 0)              (COND                 ((PLUSP N)                                  (* Looking for R = Ni =                                                             (CL:* 2 (EXPT A 2) i) =                                                             (CL:* A+Ai A+Ai) *)                  (SETQ A (%%SQRT-PERFECT (/ N 2)))                  (COND                     ((NULL A)                      (RETURN NIL)))                  (RETURN (%%MAKE-COMPLEX A A)))                 (T                                          (* N must be negative because we                                                              cannot have M and N = 0                                                              simultaneously. *)                                                             (* Looking for R = Ni =                                                             (CL:* -2 (EXPT A 2) i) =                                                             (CL:* A-Ai A-Ai) *)                    (SETQ A (%%SQRT-PERFECT (/ N -2)))                    (COND                       ((NULL A)                        (RETURN NIL)))                    (RETURN (%%MAKE-COMPLEX A (- A)))))))                    (* * At this point neither M or N is 0 %.          We need to solve for A+Bi such that (EXPT A+Bi 2) = M+iN implies M =          (minus (EXPT A 2) (EXPT B 2)) and N = (CL:* 2 A B) These requirements lead to a           quartic with four possible solutions. Two of the solutions are eliminated by           the requirement that B must be real and the third solution is eliminated by its           being on the wrong branch of SQRT. I leave the development of this quartic and           its solution as an exercise for the reader.          *)          (SETQ DELTA (%%SQRT-PERFECT (+ (CL:* M M)                                         (CL:* N N))))          (COND             ((NULL DELTA)              (RETURN NIL)))          (SETQ A (%%SQRT-PERFECT (/ (+ M DELTA)                                     2)))          (COND             ((NULL A)              (RETURN NIL)))          (SETQ B (/ N (CL:* 2 A)))          (RETURN (%%MAKE-COMPLEX A B)))))(%%OLD-SQRT-COMPLEX  (CL:LAMBDA (Z)                                             (* kbr: "29-May-86 19:42")                                                             (* The square root of a complex number                                                              returns two roots. This function                                                              returns the primary root.                                                             *)         (OR (%%SQRT-COMPLEX-PERFECT Z)             (LET ((ABS (CL:SQRT (ABS Z)))                   (PHASE (/ (PHASE Z)                             2.0)))                  (COMPLEX (CL:* ABS (CL:COS PHASE))                         (CL:* ABS (CL:SIN PHASE))))))))(DEFINEQ(ISQRT  (CL:LAMBDA (N)                                             (* kbr: "27-May-86 20:40")                    (* ISQRT: Integer square root -          isqrt (n) **2 <= n Upper and lower bounds on the result are estimated using           integer-length. On each iteration, one of the bounds is replaced by their mean.          The lower bound is returned when the bounds meet or differ by only 1.0 Initial           bounds guarantee that lg (sqrt (n)) = lg          (n) /2 iterations suffice. *)         (CL:IF (AND (INTEGERP N)                     (NOT (MINUSP N)))                (CL:DO* ((LG (INTEGER-LENGTH N))                         (LO (ASH 1 (ASH (1- LG)                                         -1)))                         (HI (+ LO (ASH LO (CL:IF (ODDP LG)                                                  -1 0)))))                       ((<= (1- HI)                         LO)                        LO)                       (LET ((MID (ASH (+ LO HI)                                       -1)))                            (CL:IF (<= (CL:* MID MID)                                    N)                                   (SETQ LO MID)                                   (SETQ HI MID))))                (CL:ERROR "ISQRT: ~S argument must be a nonnegative integer." N)))))(DECLARE: EVAL@COMPILE DONTCOPY (DECLARE: EVAL@COMPILE (RPAQ %%2PI (%%FLOAT 16585 4059))(RPAQ %%PI (%%FLOAT 16457 4059))(RPAQ %%PI/2 (%%FLOAT 16329 4059))(RPAQ %%-PI/2 (%%FLOAT 49097 4059))(RPAQ %%PI/4 (%%FLOAT 16201 4059))(RPAQ %%-PI/4 (%%FLOAT 48969 4059))(RPAQQ SIXTH-PI .5236)(RPAQ %%2/PI (%%FLOAT 16162 63875))(CONSTANTS (%%2PI (%%FLOAT 16585 4059))       (%%PI (%%FLOAT 16457 4059))       (%%PI/2 (%%FLOAT 16329 4059))       (%%-PI/2 (%%FLOAT 49097 4059))       (%%PI/4 (%%FLOAT 16201 4059))       (%%-PI/4 (%%FLOAT 48969 4059))       (SIXTH-PI .5236)       (%%2/PI (%%FLOAT 16162 63875)))))(* SIN *)(RPAQQ CMLFLOATSINCOMS ((* * %%SIN-EPSILON is sufficiently small that (SIN X)                           = X for X in interval (0 %%SIN-EPSILON)                           %. It suffices to take %%SIN-EPSILON a little bit smaller than                           (SQRT (CL:* 6 SINGLE-FLOAT-EPSILON))                           which we get by the Taylor series expansion (SIN X)                           =                           (+ X (/ (EXPT X 3)                                   6)                              ...)                           (The relative error caused by ommitting (/ (EXPT X 3)                                                                      6)                                isn't observable.)                           Comparison against %%SIN-EPSILON is used to avoid POLYEVAL microcode                            underflow when computing SIN. *)                        (DECLARE: EVAL@COMPILE DONTCOPY (CONSTANTS (%%SIN-EPSILON (%%FLOAT 14720 0)))                               )                        (* * %%SIN-PPOLY and %%SIN-QPOLY contain P and Q coefficients of Harris et al                            SIN 3374 rational approximation to (SIN X)                           in interval (0 (/ PI 2)) . *)                        (INITVARS (%%SIN-PPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 50193 50772)                                                                   (%%FLOAT 18371 47202)                                                                   (%%FLOAT 51905 54216)                                                                   (%%FLOAT 19748 29063)                                                                   (%%FLOAT 52951 41140)                                                                   (%%FLOAT 20368 50691))))                               (%%SIN-QPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 16256 0)                                                                (%%FLOAT 17252 49821)                                                                (%%FLOAT 18142 34466)                                                                (%%FLOAT 18957 45135)                                                                (%%FLOAT 19685 22067)                                                                (%%FLOAT 20280 21713)))))))(* * %%SIN-EPSILON is sufficiently small that (SIN X) = X for X in interval (0 %%SIN-EPSILON) %. It suffices to take %%SIN-EPSILON a little bit smaller than (SQRT (CL:* 6 SINGLE-FLOAT-EPSILON)) which we get by the Taylor series expansion (SIN X) = (+ X (/ (EXPT X 3) 6) ...) (The relative error caused by ommitting (/ (EXPT X 3) 6) isn't observable.) Comparison against %%SIN-EPSILON is used to avoid POLYEVAL microcode underflow when computing SIN. *)(DECLARE: EVAL@COMPILE DONTCOPY (DECLARE: EVAL@COMPILE (RPAQ %%SIN-EPSILON (%%FLOAT 14720 0))(CONSTANTS (%%SIN-EPSILON (%%FLOAT 14720 0)))))(* * %%SIN-PPOLY and %%SIN-QPOLY contain P and Q coefficients of Harris et al SIN 3374 rational approximation to (SIN X) in interval (0 (/ PI 2)) . *)(RPAQ? %%SIN-PPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 50193 50772)                                       (%%FLOAT 18371 47202)                                       (%%FLOAT 51905 54216)                                       (%%FLOAT 19748 29063)                                       (%%FLOAT 52951 41140)                                       (%%FLOAT 20368 50691))))(RPAQ? %%SIN-QPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 16256 0)                                       (%%FLOAT 17252 49821)                                       (%%FLOAT 18142 34466)                                       (%%FLOAT 18957 45135)                                       (%%FLOAT 19685 22067)                                       (%%FLOAT 20280 21713))))(DEFINEQ(CL:SIN  (CL:LAMBDA (X)                                             (* kbr: " 7-Apr-86 22:57")         (CL:IF (AND (NOT (FLOATP X))                     (NOT (COMPLEXP X)))                (SETQ X (FLOAT X)))         (TYPECASE X (FLOAT (%%SIN-FLOAT X NIL))                (COMPLEX (%%SIN-COMPLEX X)))))(%%SIN-FLOAT  (LAMBDA (X COS-FLAG)                                       (* kbr: "28-May-86 21:40")                    (* * SIN of a FLOAT X calculated via SIN 3374 rational approximation of Harris           et al. *)    (PROG (R SIGN R2 ANSWER)          (DECLARE (GLOBALVARS %%SIN-PPOLY %%SIN-QPOLY)                 (TYPE FLOATP X R SIGN R2 ANSWER))                    (* * If this function called by COS then use          (COS X) = (SIN (+ X %%PI/2)) *)          (SETQ R (CL:IF COS-FLAG (+ X %%PI/2)                         X))                    (* * First range reduce to interval (0 %%2PI) by          (SIN X) = (SIN (MOD X %%2PI)) . *)          (SETQ R (CL:MOD R %%2PI))                    (* * Next range reduce to interval (0 PI) by          (SIN (+ X PI)) = (minus (SIN X)) *)          (COND             ((> R %%PI)              (SETQ SIGN -1.0)              (SETQ R (- R %%PI)))             (T (SETQ SIGN 1.0)))                    (* * Next range reduce to interval (0 %%PI/2) by          (SIN (+ X %%PI/2)) = (SIN (minus %%PI/2 X)) *)          (COND             ((> R %%PI/2)              (SETQ R (- %%PI R))))          (COND             ((< R %%SIN-EPSILON)                    (* * If R is in the interval (0 %%SIN-EPSILON) then          (SIN R) = R to the precision that we can offer.          Return R because (1) it is desirable that          (SIN R) = R exactly for small R and (2) microcode POLYEVAL will underflow on           sufficiently small positive R. *)              (RETURN R)))                    (* * TBW: Should get rid of following (SETQ R          (/ R %%PI/2)) line by adjusting %%SIN-PPOLY %%SIN-QPOLY to compensate.          What we have is correct but slightly suboptimal.          *)          (SETQ R (/ R %%PI/2))                    (* * Now use SIN 3374 rational approximation of Harris et al.          which works on interval (0 %%PI/2) *)          (SETQ R2 (CL:* R R))          (SETQ ANSWER (CL:* SIGN R (/ (POLYEVAL R2 %%SIN-PPOLY 5)                                       (POLYEVAL R2 %%SIN-QPOLY 5))))          (RETURN ANSWER))))(%%SIN-COMPLEX  (CL:LAMBDA (Z)                                             (* sin of a complex number *)         (LET* ((X (REALPART Z))                (Y (IMAGPART Z)))               (COMPLEX (CL:* (CL:SIN X)                              (COSH Y))                      (CL:* (CL:COS X)                            (SINH Y)))))))(* COS *)(DEFINEQ(CL:COS  (CL:LAMBDA (X)                                             (* kbr: "31-Mar-86 17:34")         (CL:IF (AND (NOT (FLOATP X))                     (NOT (COMPLEXP X)))                (SETQ X (FLOAT X)))         (TYPECASE X (FLOAT (%%SIN-FLOAT X T))                (COMPLEX (%%COS-COMPLEX X)))))(%%COS-COMPLEX  (CL:LAMBDA (Z)                                             (* cosine of a complex number *)         (LET* ((X (REALPART Z))                (Y (IMAGPART Z)))               (COMPLEX (CL:* (CL:COS X)                              (COSH Y))                      (- (CL:* (CL:SIN X)                               (SINH Y))))))))(* TAN *)(RPAQQ CMLFLOATTANCOMS ((* * %%TAN-EPSILON is sufficiently small that (TAN X)                           = X for X in interval (0 %%TAN-EPSILON)                           %. It suffices to take %%TAN-EPSILON a little bit smaller than                           (SQRT (CL:* 3 SINGLE-FLOAT-EPSILON))                           which we get by the Taylor series expansion (TAN X)                           =                           (+ X (/ (EXPT X 3)                                   3)                              ...)                           (The relative error caused by ommitting (/ (EXPT X 3)                                                                      3)                                isn't observable.)                           Comparison against %%TAN-EPSILON is used to avoid POLYEVAL microcode                            underflow when computing TAN. *)                        (DECLARE: EVAL@COMPILE DONTCOPY (CONSTANTS (%%TAN-EPSILON (%%FLOAT 14720 0)))                               )                        (* * %%TAN-PPOLY and %%TAN-QPOLY contain P and Q coefficients of Harris et al                            TAN 4288 rational approximation to (TAN X)                           in interval (-PI/4 PI/4) . *)                        (INITVARS (%%TAN-PPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 49803 44451)                                                                   (%%FLOAT 18254 23362)                                                                   (%%FLOAT 51983 57389)                                                                   (%%FLOAT 19947 57965)                                                                   (%%FLOAT 53162 16965))))                               (%%TAN-QPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 16256 0)                                                                (%%FLOAT 50453 51515)                                                                (%%FLOAT 18760 65370)                                                                (%%FLOAT 52376 39517)                                                                (%%FLOAT 20221 24840)                                                                (%%FLOAT 53208 51139)))))))(* * %%TAN-EPSILON is sufficiently small that (TAN X) = X for X in interval (0 %%TAN-EPSILON) %. It suffices to take %%TAN-EPSILON a little bit smaller than (SQRT (CL:* 3 SINGLE-FLOAT-EPSILON)) which we get by the Taylor series expansion (TAN X) = (+ X (/ (EXPT X 3) 3) ...) (The relative error caused by ommitting (/ (EXPT X 3) 3) isn't observable.) Comparison against %%TAN-EPSILON is used to avoid POLYEVAL microcode underflow when computing TAN. *)(DECLARE: EVAL@COMPILE DONTCOPY (DECLARE: EVAL@COMPILE (RPAQ %%TAN-EPSILON (%%FLOAT 14720 0))(CONSTANTS (%%TAN-EPSILON (%%FLOAT 14720 0)))))(* * %%TAN-PPOLY and %%TAN-QPOLY contain P and Q coefficients of Harris et al TAN 4288 rational approximation to (TAN X) in interval (-PI/4 PI/4) . *)(RPAQ? %%TAN-PPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 49803 44451)                                       (%%FLOAT 18254 23362)                                       (%%FLOAT 51983 57389)                                       (%%FLOAT 19947 57965)                                       (%%FLOAT 53162 16965))))(RPAQ? %%TAN-QPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 16256 0)                                       (%%FLOAT 50453 51515)                                       (%%FLOAT 18760 65370)                                       (%%FLOAT 52376 39517)                                       (%%FLOAT 20221 24840)                                       (%%FLOAT 53208 51139))))(DEFINEQ(CL:TAN  (CL:LAMBDA (X)                                             (* kbr: "28-May-86 20:56")         (TYPECASE X (COMPLEX (%%TAN-COMPLEX X))                (NUMBER (%%TAN-FLOAT (FLOAT X)))                (T (LISPERROR "NON-NUMERIC ARG" X)))))(%%TAN-FLOAT  (LAMBDA (X)                                                (* kbr: "28-May-86 22:36")                    (* * TAN of a FLOAT X calculated via TAN 4288 rational approximation of Harris           et al. *)    (PROG (R R2 RECIPFLG ANSWER)          (DECLARE (GLOBALVARS %%TAN-PPOLY %%TAN-QPOLY)                 (TYPE FLOATP X R R2 ANSWER))                    (* * First, range reduce to (0 PI) *)          (SETQ R (CL:MOD X PI))                    (* * Next, range reduce to (-PI/4 PI/4) using          (TAN (+ X PI/2)) = (TAN (minus PI/2 X)) to get into interval          (-PI/2 PI/2) and then (TAN X) = (/ (TAN (minus PI/2 X))) to get into interval          (-PI/4 PI/4) *)          (COND             ((> R %%PI/2)              (SETQ R (- R %%PI))              (COND                 ((< R %%-PI/4)                  (SETQ RECIPFLG T)                  (SETQ R (- %%-PI/2 R)))))             (T (COND                   ((> R %%PI/4)                    (SETQ RECIPFLG T)                    (SETQ R (- %%PI/2 R))))))          (COND             ((< (ABS R)               %%TAN-EPSILON)                    (* * If R is in the interval (0 %%TAN-EPSILON) then          (TAN R) = R to the precision that we can offer.          Return R because (1) it is desirable that          (TAN R) = R exactly for small R and (2) microcode POLYEVAL will underflow on           sufficiently small positive R. *)              (SETQ ANSWER (COND                              (RECIPFLG (/ R))                              (T R)))              (RETURN ANSWER)))                    (* * TBW: Should get rid of following (SETQ R          (/ R %%PI/2)) line by adjusting %%SIN-PPOLY %%SIN-QPOLY to compensate.          What we have is correct but slightly suboptimal.          *)          (SETQ R (/ R %%PI/4))                    (* * Now use TAN 4288 rational approximation of Harris et al.          which works on interval (0 %%PI/4) *)          (SETQ R2 (CL:* R R))          (SETQ ANSWER (CL:* R (/ (POLYEVAL R2 %%TAN-PPOLY 5)                                  (POLYEVAL R2 %%TAN-QPOLY 6))))          (COND             (RECIPFLG (SETQ ANSWER (/ ANSWER))))          (RETURN ANSWER))))(%%TAN-COMPLEX  (CL:LAMBDA (Z)                                             (* tan of a complex number there was a                                                              nicer algorithm but it turned out not                                                              to work so well. *)         (LET* ((NUM (CL:SIN Z))                (DENOM (CL:COS Z)))               (CL:IF (ZEROP DENOM)                      (CL:ERROR "~S undefined tangent." Z)                      (/ NUM DENOM))))))(* ASIN *)(RPAQQ CMLFLOATASINCOMS ((* * %%ASIN-EPSILON is sufficiently small that (ASIN X)                            = X for X in interval (0 %%ASIN-EPSILON)                            %. It suffices to take %%ASIN-EPSILON a little bit smaller than                            (CL:* 2 SINGLE-FLOAT-EPSILON)                            which we get by the Taylor series expansion (ASIN X)                            =                            (+ X (/ (EXPT X 3)                                    6)                               ...)                            (The relative error caused by ommitting (/ (EXPT X 3)                                                                       6)                                 isn't observable.)                            Comparison against %%ASIN-EPSILON is used to avoid POLYEVAL microcode                             underflow when computing SIN. *)                         (DECLARE: EVAL@COMPILE DONTCOPY (CONSTANTS (%%ASIN-EPSILON (%%FLOAT 14720 0)                                                                           )))                         (* * %%ASIN-PPOLY and %%ASIN-QPOLY contain P and Q coefficients of Harris et                             al ARCSN 4671 rational approximation to (ASIN X)                            in interval (0 (SQRT .5)) . *)                         (INITVARS (%%ASIN-PPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 16007 50045)                                                                     (%%FLOAT 49549 8020)                                                                     (%%FLOAT 17236 15848)                                                                     (%%FLOAT 50285 63464)                                                                     (%%FLOAT 17650 31235)                                                                     (%%FLOAT 50403 62852)                                                                     (%%FLOAT 17440 39471))))                                (%%ASIN-QPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 16256 0)                                                                  (%%FLOAT 49672 25817)                                                                  (%%FLOAT 17308 55260)                                                                  (%%FLOAT 50326 38098)                                                                  (%%FLOAT 17674 22210)                                                                  (%%FLOAT 50417 22451)                                                                  (%%FLOAT 17440 39471)))))))(* * %%ASIN-EPSILON is sufficiently small that (ASIN X) = X for X in interval (0 %%ASIN-EPSILON) %. It suffices to take %%ASIN-EPSILON a little bit smaller than (CL:* 2 SINGLE-FLOAT-EPSILON) which we get by the Taylor series expansion (ASIN X) = (+ X (/ (EXPT X 3) 6) ...) (The relative error caused by ommitting (/ (EXPT X 3) 6) isn't observable.) Comparison against %%ASIN-EPSILON is used to avoid POLYEVAL microcode underflow when computing SIN. *)(DECLARE: EVAL@COMPILE DONTCOPY (DECLARE: EVAL@COMPILE (RPAQ %%ASIN-EPSILON (%%FLOAT 14720 0))(CONSTANTS (%%ASIN-EPSILON (%%FLOAT 14720 0)))))(* * %%ASIN-PPOLY and %%ASIN-QPOLY contain P and Q coefficients of Harris et al ARCSN 4671 rational approximation to (ASIN X) in interval (0 (SQRT .5)) . *)(RPAQ? %%ASIN-PPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 16007 50045)                                        (%%FLOAT 49549 8020)                                        (%%FLOAT 17236 15848)                                        (%%FLOAT 50285 63464)                                        (%%FLOAT 17650 31235)                                        (%%FLOAT 50403 62852)                                        (%%FLOAT 17440 39471))))(RPAQ? %%ASIN-QPOLY (%%MAKE-ARRAY (LIST (%%FLOAT 16256 0)                                        (%%FLOAT 49672 25817)                                        (%%FLOAT 17308 55260)                                        (%%FLOAT 50326 38098)                                        (%%FLOAT 17674 22210)                                        (%%FLOAT 50417 22451)                                        (%%FLOAT 17440 39471))))(DEFINEQ(ASIN  (CL:LAMBDA (X)                                             (* kbr: "30-May-86 16:49")         (TYPECASE X (FLOAT (%%ASIN-FLOAT X))                (COMPLEX (%%ASIN-COMPLEX X))                (NUMBER (ASIN (FLOAT X))))))(%%ASIN-FLOAT  (LAMBDA (X ACOS-FLAG)                                      (* kbr: "30-May-86 16:46")                    (* * (ASIN X) for float X calculated via ARCSN 4671 rational approximation of           Harris et al. *)    (PROG (NEGATIVE REDUCED R R2 ANSWER)          (DECLARE (GLOBALVARS %%ASIN-PPOLY %%ASIN-QPOLY))          (SETQ R X)          (COND             ((OR (< R -1.0)                  (> R 1.0))              (ERROR "ARCSIN: arg not in range" R)))          (COND             ((< R 0.0)                    (* * Range reduce to (0 1) via identity (ASIN          (minus X)) = (minus (ASIN X)) *)              (SETQ NEGATIVE T)              (SETQ R (- R))))          (COND             ((> R .5)                    (* * Range reduce to (0 .5) via identity          (ASIN X) = (minus %%PI/2 (CL:* 2.0 (ASIN          (CL:SQRT (CL:* .5 (minus 1.0 R)))))) Avoids numerical instability calculating          (ASIN X) for X near one. SIN is horizontally flat near %%PI/2 so calculating          (ASIN X) by rational approximation wouldn't work well for X near          (SIN %%PI/2) = 1 *)              (SETQ REDUCED T)              (SETQ R (CL:SQRT (CL:* .5 (- 1.0 R))))))                    (* * R is now in range (0 .5) Use ARCSN 4671 rational approximation to           calculate (ASIN R) *)          (SETQ ANSWER (COND                          ((< R %%ASIN-EPSILON)                    (* * If R is in the interval (0 %%SIN-EPSILON) then          (ASIN R) = R to the precision that we can offer.          Return R because (1) it is desirable that          (ASIN R) = R exactly for small R and (2) microcode POLYEVAL will underflow on           sufficiently small positive R. *)                           R)                          (T (SETQ R2 (CL:* R R))                             (CL:* R (/ (POLYEVAL R2 %%ASIN-PPOLY 6)                                        (POLYEVAL R2 %%ASIN-QPOLY 6))))))          (COND             (REDUCED (SETQ ANSWER (- %%PI/2 (CL:* 2.0 ANSWER)))))          (COND             (NEGATIVE (SETQ ANSWER (- ANSWER))))          (COND             (ACOS-FLAG                     (* * In case we want (ACOS X) then use identity          (ACOS X) = (minus %%PI/2 (ASIN X)) *)                    (SETQ ANSWER (- %%PI/2 ANSWER))))          (RETURN ANSWER))))(%%ASIN-COMPLEX  (CL:LAMBDA (Z)                                             (* kbr: "27-May-86 22:38")         (%%COMPLEX-MINUS (%%COMPLEX-TIMESI (CL:LOG (+ (%%COMPLEX-TIMESI Z)                                                       (CL:SQRT (- 1 (CL:* Z Z))))))))))(* ACOS *)(DEFINEQ(ACOS  (CL:LAMBDA (X)                                             (* kbr: "30-May-86 16:49")         (TYPECASE X (FLOAT (%%ASIN-FLOAT X T))                (COMPLEX (%%ACOS-COMPLEX X))                (NUMBER (ACOS (FLOAT X))))))(%%ACOS-COMPLEX  (CL:LAMBDA (Z)                                             (* kbr: "27-May-86 22:31")         (%%COMPLEX-MINUS (%%COMPLEX-TIMESI (CL:LOG (+ Z (%%COMPLEX-TIMESI (CL:SQRT                                                                            (- 1 (CL:* Z Z)))))))))))(* ATAN *)(DEFINEQ(CL:ATAN  (CL:LAMBDA (X &OPTIONAL Y)                                 (* kbr: "14-May-86 11:41")         (COND            (Y (CL:IF (OR (COMPLEXP X)                          (COMPLEXP Y))                      (CL:ERROR "~S and ~S both complex." X Y))               (%%ATAN-FLOAT (FLOAT X)                      (FLOAT Y)))            ((COMPLEXP X)             (%%ATAN-COMPLEX X))            (T (%%ATAN-FLOAT (FLOAT X))))))(%%ATAN1  (CL:LAMBDA (X)                                             (* kbr: "24-Jun-86 20:35")         (COND            ((MINUSP X)             (- (%%ATAN1 (- X))))            ((< X 2-SQRT3)             (- %%PI/2 (%%ATAN2 (/ X))))            ((< X 1)             (- (+ %%PI/2 SIXTH-PI)                (%%ATAN2 (/ (+ SQRT3 X)                            (1- (CL:* X SQRT3))))))            ((< X INV-2-SQRT3)             (LET* ((INV (/ X)))                   (- (%%ATAN2 (/ (+ SQRT3 INV)                                  (1- (CL:* SQRT3 INV))))                      SIXTH-PI)))            (T (%%ATAN2 X)))))(%%ATAN2  (CL:LAMBDA (X)         (CL:DO* ((SQR (- (/ (CL:* X X))))                  (INT 1 (+ 2 INT))                  (OLD 0 VAL)                  (POW (/ X)                       (CL:* POW SQR))                  (VAL POW (+ VAL (/ POW INT))))                ((= OLD VAL)                 (- %%PI/2 VAL)))))(%%ATAN-DOMAIN-CHECK  (CL:LAMBDA (Z)                                             (* kbr: "27-May-86 22:42")                                                             (* Return T if Z is in the domain of                                                              ATAN. ATAN is singular at i and -i.                                                             *)         (NOT (AND (ZEROP (REALPART Z))                   (= (ABS (IMAGPART Z))                      1)))))(%%ATAN-FLOAT  (CL:LAMBDA (Y &OPTIONAL X)                                 (* kbr: "24-Jun-86 20:37")         (COND            ((NULL X)             (CL:IF (ZEROP Y)                    0.0                    (%%ATAN1 Y)))            ((= Y X 0)             (CL:ERROR "Error in double entry atan both 0."))            ((= X 0)             (CL:* (%%SIGNUM Y)                   %%PI/2))            ((= Y 0)             (CL:IF (PLUSP X)                    0 %%PI))            ((AND (PLUSP X)                  (PLUSP Y))             (%%ATAN1 (/ Y X)))            ((PLUSP Y)             (- %%PI (%%ATAN1 (/ (- Y)                                 X))))            ((PLUSP X)             (- (%%ATAN1 (/ Y (- X)))))            (T (- (%%ATAN1 (/ Y X))                  %%PI)))))(%%ATAN-COMPLEX  (CL:LAMBDA (Z)         (CL:IF (%%ATAN-DOMAIN-CHECK Z)                (LET ((I (%%COMPLEX-TIMESI Z)))                     (%%COMPLEX-MINUS (%%COMPLEX-TIMESI (CL:* .5 (CL:LOG (/ (+ 1 I)                                                                            (- 1 I)))))))                (CL:ERROR "Argument not in domain for atan. ~S" Z)))))(* CIS *)(DEFINEQ(CIS  (CL:LAMBDA (THETA)                                         (* Return cos (Theta) + i sin                                                             (Theta)%. *)         (CL:IF (COMPLEXP THETA)                (CL:ERROR "Argument to CIS is complex: ~S" THETA)                (COMPLEX (CL:COS THETA)                       (CL:SIN THETA))))))(* SINH COSH TANH *)(DEFINEQ(SINH  (CL:LAMBDA (X)                    (* Hyperbolic trig functions. Each of the hyperbolic trig functions is           calculated directly from their definition.          Exp (x) is calculated only once for efficiency.          They all work with complex arguments without modification.          *)         (LET ((Z (EXP X)))              (/ (- Z (/ Z))                 2))))(COSH  (CL:LAMBDA (X)         (LET ((Z (EXP X)))              (/ (+ Z (/ Z))                 2))))(TANH  (CL:LAMBDA (X)                                             (* Different form than in the manual.                                                             Does much better. *)         (LET* ((Z (EXP (CL:* 2 X)))                (Y (/ Z)))               (- (/ (1+ Y))                  (/ (1+ Z)))))))(* ASINH ACOSH ATANH *)(DEFINEQ(ASINH  (CL:LAMBDA (X)                                             (* kbr: "27-May-86 22:43")         (CL:LOG (+ X (CL:SQRT (+ (CL:* X X)                                  1))))))(ACOSH  (CL:LAMBDA (X)                                             (* kbr: "27-May-86 22:45")         (CL:LOG (+ X (CL:SQRT (- (CL:* X X)                                  1))))))(ATANH  (CL:LAMBDA (X)                                             (* kbr: "27-May-86 22:46")         (CL:IF (%%ATANH-DOMAIN-CHECK X)                (CL:* .5 (CL:LOG (/ (1+ X)                                    (- 1 X))))                (CL:ERROR "~S argument out of range." X))))(%%ATANH-DOMAIN-CHECK  (CL:LAMBDA (Z)                                             (* kbr: "27-May-86 22:49")                                                             (* Return T if Z is in the domain of                                                              ATANH. ATANH is singular at 1 and -1.0                                                              *)         (NOT (AND (ZEROP (IMAGPART Z))                   (= (ABS (REALPART Z))                      1))))))(DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS (ADDTOVAR NLAMA )(ADDTOVAR NLAML )(ADDTOVAR LAMA           %%ATANH-DOMAIN-CHECK ATANH ACOSH ASINH TANH COSH SINH CIS %%ATAN-COMPLEX %%ATAN-FLOAT                 %%ATAN-DOMAIN-CHECK %%ATAN2 %%ATAN1 CL:ATAN %%ACOS-COMPLEX ACOS %%ASIN-COMPLEX ASIN                 %%TAN-COMPLEX CL:TAN %%COS-COMPLEX CL:COS %%SIN-COMPLEX CL:SIN ISQRT                 %%OLD-SQRT-COMPLEX %%SQRT-PERFECT CL:SQRT %%LOG-COMPLEX CL:LOG %%EXPT-COMPLEX-POWER                 %%EXPT-COMPLEX %%EXPT-INTEGER CL:EXPT %%EXP-COMPLEX %%EXP-FLOAT EXP COMPLEX                 %%COMPLEX-ABS TRUNCATE PHASE))(PUTPROPS CMLFLOAT COPYRIGHT ("Xerox Corporation" 1986))(DECLARE: DONTCOPY  (FILEMAP (NIL (4760 5764 (%%FLOAT 4770 . 4918) (%%MAKE-ARRAY 4920 . 5762)) (8201 15355 (PHASE 8211 . 8714) (TRUNCATE 8716 . 11182) (%%COMPLEX-ABS 11184 . 11659) (COMPLEX 11661 . 13148) (\FLOAT 13150 . 15353)) (18239 20654 (EXP 18249 . 18817) (%%EXP-FLOAT 18819 . 20306) (%%EXP-COMPLEX 20308 . 20652)) (20674 24425 (CL:EXPT 20684 . 22053) (%%EXPT-INTEGER 22055 . 23229) (%%EXPT-FLOAT 23231 . 23541) (%%EXPT-COMPLEX 23543 . 23976) (%%EXPT-COMPLEX-POWER 23978 . 24423)) (26810 30513 (CL:LOG 26820 . 27445) (%%LOG-FLOAT 27447 . 29212) (%%LOG-COMPLEX 29214 . 29425) (%%OLD-LOG-FLOAT 29427 . 30511)) (30533 40762 (CL:SQRT 30543 . 31066) (%%SQRT-PERFECT 31068 . 31899) (%%SQRT-INTEGER 31901 . 32331) (%%SQRT-INTEGER-PERFECT 32333 . 32819) (%%SQRT-FLOAT 32821 . 34349) (%%SQRT-RATIO 34351 . 34775) (%%SQRT-RATIO-PERFECT 34777 . 35640) (%%SQRT-COMPLEX 35642 . 37028) (%%SQRT-COMPLEX-PERFECT 37030 . 39977) (%%OLD-SQRT-COMPLEX 39979 . 40760)) (40763 42124 (ISQRT 40773 . 42122)) (46631 49570 (CL:SIN 46641 . 46971) (%%SIN-FLOAT 46973 . 49204) (%%SIN-COMPLEX 49206 . 49568)) (49589 50303 (CL:COS 49599 . 49927) (%%COS-COMPLEX 49929 . 50301)) (54002 57128 (CL:TAN 54012 . 54284) (%%TAN-FLOAT 54286 . 56600) (%%TAN-COMPLEX 56602 . 57126)) (61390 64391 (ASIN 61400 . 61657) (%%ASIN-FLOAT 61659 . 64100) (%%ASIN-COMPLEX 64102 . 64389)) (64411 64992 (ACOS 64421 . 64680) (%%ACOS-COMPLEX 64682 . 64990)) (65012 68168 (CL:ATAN 65022 . 65476) (%%ATAN1 65478 . 66131) (%%ATAN2 66133 . 66457) (%%ATAN-DOMAIN-CHECK 66459 . 66961) (%%ATAN-FLOAT 66963 . 67784) (%%ATAN-COMPLEX 67786 . 68166)) (68187 68573 (CIS 68197 . 68571)) (68603 69482 (SINH 68613 . 69034) (COSH 69036 . 69150) (TANH 69152 . 69480)) (69515 70747 (ASINH 69525 . 69726) (ACOSH 69728 . 69929) (ATANH 69931 . 70236) (%%ATANH-DOMAIN-CHECK 70238 . 70745)))))STOP