(import (rnrs)) ;R6RS (import (rnrs base)) ;R6RS (import (rnrs arithmetic flonums)) ;R6RS (import (scheme r5rs)) ;R7RS (import (scheme inexact)) ;R7RS
(exp z) (log z) (log z1 z2) (sin z) (cos z) (tan z) (asin z) (acos z) (atan z) (atan y x) ;; From (rnrs arithmetic flonums) (flexp fl) (fllog fl) (fllog fl1 fl2) (flsin fl) (flcos fl) (fltan fl) (flasin fl) (flacos fl) (flatan fl) (flatan fl1 fl2)
In general, the transcendental functions log, asin (arcsine), acos (arccosine), and atan (arctangent) are multiply defined.
The value of log z is defined to be the one whose imaginary part lies in the range from -\[*p] (inclusive if -0.0 is distinguished, exclusive otherwise) to \[*p] (inclusive).
The value of log 0 is mathematically undefined. However, (log 0.0) returns -inf.0 if the implementation supports infinities, and (log -0.0) returns approximately -inf.0+\[*p]i if the implementation supports minus zero.
The value of log z for non-real z is defined in terms of log on real numbers as
log z = log |z| + (angle z)i
where angle z is the angle of z = a\[md]exp(ib) specified as:
angle z = b + 2\[*p]n
with -\[*p] <= angle z <= \[*p] and angle z = b + 2\[*p]n for some integer n.
log z b = (log z)\[f/](log b)
With the one-argument version of log defined as above, their values are according to the following formulas:
asin z = -i log(iz + sqrt(1 - z²)) acos z = \[*p]/2 - asin z atan z = (log(1 + iz) - log(1 - iz))/(2i)
The range of (atan y x) is as in the following table. The asterisk (*) indicates that the entry applies to implementations that distinguish minus zero (as in IEEE 754).
Table showing atan2 ranges [1my condition x condition range of result r[0m y = 0.0 x > 0.0 0.0 * y = +0.0 x > 0.0 +0.0 * y = -0.0 x > 0.0 -0.0 y > 0.0 x > 0.0 0.0 < r < /2 y > 0.0 x = 0.0 /2 y > 0.0 x < 0.0 /2 < r < y = 0.0 x < 0 * y = +0.0 x < 0.0 * y = -0.0 x < 0.0 - y < 0.0 x < 0.0 - < r < -/2 y < 0.0 x = 0.0 -/2 y < 0.0 x > 0.0 -/2 < r < 0.0 y = 0.0 x = 0.0 undefined * y = +0.0 x = +0.0 +0.0 * y = -0.0 x = +0.0 -0.0 * y = +0.0 x = -0.0 * y = -0.0 x = -0.0 - * y = +0.0 x = 0 /2 * y = -0.0 x = 0 -/2
The two-argument version of atan is commonly called atan2. Please refer to to the following sources for more detailed discussion of branch cuts, boundary conditions, and implementation of these functions.
Guy Lewis Steele Jr. Common Lisp: The Language, second edition. Digital Press, Burlington MA, 1990.
Paul Penfield, Jr. Principal values and branch cuts in complex APL. In APL 81 Conference Proceedings, pages 248–256. ACM SIGAPL, San Francisco, September 1981. Proceedings published as APL Quote Quad 12(1), ACM, September 1981.
Implementations that use IEEE binary floating-point arithmetic should follow the relevant standards for these procedures.
;; The floating point numbers shown below are approximate. ;; R7RS implementations are not required to support complex ;; numbers. (exp +inf.0) => +inf.0 (exp -inf.0) => 0.0 (log +inf.0) => +inf.0 (log 0.0) => -inf.0 (log 0) => &assertion exception (log -inf.0) => +inf.0+3.141592653589793i (atan -inf.0) => -1.5707963267948965 (atan +inf.0) => 1.5707963267948965 (log -1.0+0.0i) => 0.0+3.141592653589793i (log -1.0-0.0i) => 0.0-3.141592653589793i ; if -0.0 is distinguished (flexp +inf.0) => +inf.0 (flexp -inf.0) => 0.0 (fllog +inf.0) => +inf.0 (fllog 0.0) => -inf.0 (fllog -0.0) => unspecified ; if -0.0 is distinguished (fllog -inf.0) => +nan.0 (flatan -inf.0) => -1.5707963267948965 (flatan +inf.0) => 1.5707963267948965
The two-argument version of atan appears to have first appeared in FORTRAN-IV some time before 1972 under the names ATAN2 and DATAN2. The following manual describes it as computing atan(Arg1/Arg2): Digital Equipment Corporation, FORTRAN IV Programmer's Reference Manual, Maynard, Massachusetts, 1973.