math: doc

R=r
DELTA=173  (74 added, 14 deleted, 85 changed)
OCL=25753
CL=25767
This commit is contained in:
Russ Cox 2009-03-05 13:31:01 -08:00
parent 83de0698d6
commit dfc3910afa
18 changed files with 170 additions and 110 deletions

View file

@ -13,21 +13,18 @@ import "math"
* Arctan is called after appropriate range reduction. * Arctan is called after appropriate range reduction.
*/ */
func Asin(arg float64) float64 { // Asin returns the arc sine of x.
var temp, x float64; func Asin(x float64) float64 {
var sign bool; sign := false;
sign = false;
x = arg;
if x < 0 { if x < 0 {
x = -x; x = -x;
sign = true; sign = true;
} }
if arg > 1 { if x > 1 {
return NaN(); return NaN();
} }
temp = Sqrt(1 - x*x); temp := Sqrt(1 - x*x);
if x > 0.7 { if x > 0.7 {
temp = Pi/2 - Atan(temp/x); temp = Pi/2 - Atan(temp/x);
} else { } else {
@ -40,9 +37,10 @@ func Asin(arg float64) float64 {
return temp; return temp;
} }
func Acos(arg float64) float64 { // Acos returns the arc cosine of x.
if arg > 1 || arg < -1 { func Acos(x float64) float64 {
if x > 1 || x < -1 {
return NaN(); return NaN();
} }
return Pi/2 - Asin(arg); return Pi/2 - Asin(x);
} }

View file

@ -57,9 +57,11 @@ func satan(arg float64) float64 {
* atan makes its argument positive and * atan makes its argument positive and
* calls the inner routine satan. * calls the inner routine satan.
*/ */
func Atan(arg float64) float64 {
if arg > 0 { // Atan returns the arc tangent of x.
return satan(arg); func Atan(x float64) float64 {
if x > 0 {
return satan(x);
} }
return -satan(-arg); return -satan(-x);
} }

View file

@ -6,23 +6,23 @@ package math
import "math" import "math"
/* // Atan returns the arc tangent of y/x, using
* atan2 discovers what quadrant the angle // the signs of the two to determine the quadrant
* is in and calls atan. // of the return value.
*/ func Atan2(x, y float64) float64 {
func Atan2(arg1, arg2 float64) float64 { // Determine the quadrant and call atan.
if arg1+arg2 == arg1 { if x+y == x {
if arg1 >= 0 { if x >= 0 {
return Pi/2; return Pi/2;
} }
return -Pi/2; return -Pi/2;
} }
x := Atan(arg1/arg2); q := Atan(x/y);
if arg2 < 0 { if y < 0 {
if x <= 0 { if q <= 0 {
return x + Pi; return q + Pi;
} }
return x - Pi; return q - Pi;
} }
return x; return q;
} }

View file

@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// The math package provides basic constants and mathematical functions.
package math package math
// Mathematical constants.
// Reference: http://www.research.att.com/~njas/sequences/Axxxxxx
const ( const (
// Mathematical constants.
// Reference: http://www.research.att.com/~njas/sequences/Axxxxxx
E = 2.71828182845904523536028747135266249775724709369995957496696763; // A001113 E = 2.71828182845904523536028747135266249775724709369995957496696763; // A001113
Pi = 3.14159265358979323846264338327950288419716939937510582097494459; // A000796 Pi = 3.14159265358979323846264338327950288419716939937510582097494459; // A000796
Phi = 1.61803398874989484820458683436563811772030917980576286213544862; // A001622 Phi = 1.61803398874989484820458683436563811772030917980576286213544862; // A001622
@ -22,3 +22,5 @@ const (
Ln10 = 2.30258509299404568401799145468436420760110148862877297603332790; // A002392 Ln10 = 2.30258509299404568401799145468436420760110148862877297603332790; // A002392
Log10E = 1/Ln10; Log10E = 1/Ln10;
) )
// BUG(rsc): The manual should define the special cases for all of these functions.

View file

@ -82,6 +82,13 @@ import "math"
// compiler will convert from decimal to binary accurately enough // compiler will convert from decimal to binary accurately enough
// to produce the hexadecimal values shown. // to produce the hexadecimal values shown.
// Exp returns e^x, the base-e exponential of x.
//
// Special cases are:
// Exp(+Inf) = +Inf
// Exp(NaN) = NaN
// Very large values overflow to -Inf or +Inf.
// Very small values underflow to 1.
func Exp(x float64) float64 { func Exp(x float64) float64 {
const ( const (
Ln2Hi = 6.93147180369123816490e-01; Ln2Hi = 6.93147180369123816490e-01;

View file

@ -4,10 +4,11 @@
package math package math
func Fabs(arg float64) float64 { // Fabs returns the absolute value of x.
if arg < 0 { func Fabs(x float64) float64 {
return -arg; if x < 0 {
return -x;
} }
return arg; return x;
} }

View file

@ -6,23 +6,20 @@ package math
import "math" import "math"
/* // Floor returns the greatest integer value less than or equal to x.
* floor and ceil-- greatest integer <= arg func Floor(x float64) float64 {
* (resp least >=) if x < 0 {
*/ d, fract := Modf(-x);
func Floor(arg float64) float64 {
if arg < 0 {
d, fract := Modf(-arg);
if fract != 0.0 { if fract != 0.0 {
d = d+1; d = d+1;
} }
return -d; return -d;
} }
d, fract := Modf(arg); d, fract := Modf(x);
return d; return d;
} }
func Ceil(arg float64) float64 { // Ceil returns the least integer value greater than or equal to x.
return -Floor(-arg); func Ceil(x float64) float64 {
return -Floor(-x);
} }

View file

@ -10,6 +10,7 @@ import "math"
* floating-point mod func without infinity or NaN checking * floating-point mod func without infinity or NaN checking
*/ */
// Fmod returns the floating-point remainder of x/y.
func Fmod(x, y float64) float64 { func Fmod(x, y float64) float64 {
if y == 0 { if y == 0 {
return x; return x;

View file

@ -12,6 +12,8 @@ package math
* Vol. 27, Number 6, pp. 577-581, Nov. 1983 * Vol. 27, Number 6, pp. 577-581, Nov. 1983
*/ */
// Hypot computes Sqrt(p*p + q*q), taking care to avoid
// unnecessary overflow and underflow.
func Hypot(p, q float64) float64 { func Hypot(p, q float64) float64 {
if p < 0 { if p < 0 {
p = -p; p = -p;

View file

@ -70,6 +70,13 @@ import "math"
// compiler will convert from decimal to binary accurately enough // compiler will convert from decimal to binary accurately enough
// to produce the hexadecimal values shown. // to produce the hexadecimal values shown.
// Log returns the natural logarithm of x.
//
// Special cases are:
// Log(+Inf) = +Inf
// Log(0) = -Inf
// Log(x < 0) = NaN
// Log(NaN) = NaN
func Log(x float64) float64 { func Log(x float64) float64 {
const ( const (
Ln2Hi = 6.93147180369123816490e-01; /* 3fe62e42 fee00000 */ Ln2Hi = 6.93147180369123816490e-01; /* 3fe62e42 fee00000 */
@ -113,11 +120,12 @@ func Log(x float64) float64 {
return k*Ln2Hi - ((hfsq-(s*(hfsq+R)+k*Ln2Lo)) - f); return k*Ln2Hi - ((hfsq-(s*(hfsq+R)+k*Ln2Lo)) - f);
} }
func Log10(arg float64) float64 { // Log10 returns the decimal logarthm of x.
if arg <= 0 { // The special cases are the same as for Log.
func Log10(x float64) float64 {
if x <= 0 {
return NaN(); return NaN();
} }
return Log(arg) * (1/Ln10); return Log(x) * (1/Ln10);
} }

View file

@ -6,7 +6,7 @@ package math
import "math" import "math"
// x^y: exponentiation // Pow returns x**y, the base-x exponential of y.
func Pow(x, y float64) float64 { func Pow(x, y float64) float64 {
// TODO: x or y NaN, ±Inf, maybe ±0. // TODO: x or y NaN, ±Inf, maybe ±0.
switch { switch {

View file

@ -15,6 +15,7 @@ package math
var pow10tab [70]float64; var pow10tab [70]float64;
// Pow10 returns 10**x, the base-10 exponential of x.
func Pow10(e int) float64 { func Pow10(e int) float64 {
if e < 0 { if e < 0 {
return 1/Pow10(-e); return 1/Pow10(-e);

View file

@ -7,14 +7,46 @@ package math
// implemented in C, in ../../runtime // implemented in C, in ../../runtime
// perhaps one day the implementations will move here. // perhaps one day the implementations will move here.
func Float32bits(f float32) (b uint32) // Float32bits returns the IEEE 754 binary representation of f.
func Float32frombits(b uint32) (f float32) func Float32bits(f float32) (b uint32)
func Float64bits(f float64) (b uint64)
func Float64frombits(b uint64) (f float64) // Float32frombits returns the floating point number corresponding
func Frexp(f float64) (frac float64, exp int) // to the IEEE 754 binary representation b.
func Inf(sign int32) (f float64) func Float32frombits(b uint32) (f float32)
func IsInf(f float64, sign int) (is bool)
func IsNaN(f float64) (is bool) // Float64bits returns the IEEE 754 binary representation of f.
func Ldexp(frac float64, exp int) (f float64) func Float64bits(f float64) (b uint64)
func Modf(f float64) (integer float64, frac float64)
func NaN() (f float64) // Float64frombits returns the floating point number corresponding
// the IEEE 754 binary representation b.
func Float64frombits(b uint64) (f float64)
// Frexp breaks f into a normalized fraction
// and an integral power of two.
// It returns frac and exp satisfying f == frac × 2<sup>exp</sup>,
// with the absolute value of frac in the interval [½, 1).
func Frexp(f float64) (frac float64, exp int)
// Inf returns positive infinity if sign >= 0, negative infinity if sign < 0.
func Inf(sign int32) (f float64)
// IsInf returns whether f is an infinity, according to sign.
// If sign > 0, IsInf returns whether f is positive infinity.
// If sign < 0, IsInf returns whether f is negative infinity.
// If sign == 0, IsInf returns whether f is either infinity.
func IsInf(f float64, sign int) (is bool)
// IsNaN returns whether f is an IEEE 754 ``not-a-number'' value.
func IsNaN(f float64) (is bool)
// Ldexp is the inverse of Frexp.
// It returns frac × 2<sup>exp</sup>.
func Ldexp(frac float64, exp int) (f float64)
// Modf returns integer and fractional floating-point numbers
// that sum to f.
// Integer and frac have the same sign as f.
func Modf(f float64) (integer float64, frac float64)
// NaN returns an IEEE 754 ``not-a-number'' value.
func NaN() (f float64)

View file

@ -6,7 +6,7 @@ package math
import "math" import "math"
func sinus(arg float64, quad int) float64 { func sinus(x float64, quad int) float64 {
// Coefficients are #3370 from Hart & Cheney (18.80D). // Coefficients are #3370 from Hart & Cheney (18.80D).
const const
( (
@ -20,7 +20,6 @@ func sinus(arg float64, quad int) float64 {
Q2 = .9463096101538208180571257e4; Q2 = .9463096101538208180571257e4;
Q3 = .1326534908786136358911494e3; Q3 = .1326534908786136358911494e3;
) )
x := arg;
if(x < 0) { if(x < 0) {
x = -x; x = -x;
quad = quad+2; quad = quad+2;
@ -52,13 +51,15 @@ func sinus(arg float64, quad int) float64 {
return temp1/temp2; return temp1/temp2;
} }
func Cos(arg float64) float64 { // Cos returns the cosine of x.
if arg < 0 { func Cos(x float64) float64 {
arg = -arg; if x < 0 {
x = -x;
} }
return sinus(arg, 1); return sinus(x, 1);
} }
func Sin(arg float64) float64 { // Sin returns the sine of x.
return sinus(arg, 0); func Sin(x float64) float64 {
return sinus(x, 0);
} }

View file

@ -7,19 +7,19 @@ package math
import "math" import "math"
/* /*
* sinh(arg) returns the hyperbolic sine of its floating- * Sinh(x) returns the hyperbolic sine of x
* point argument.
* *
* The exponential func is called for arguments * The exponential func is called for arguments
* greater in magnitude than 0.5. * greater in magnitude than 0.5.
* *
* A series is used for arguments smaller in magnitude than 0.5. * A series is used for arguments smaller in magnitude than 0.5.
* *
* cosh(arg) is computed from the exponential func for * Cosh(x) is computed from the exponential func for
* all arguments. * all arguments.
*/ */
func Sinh(arg float64) float64 { // Sinh returns the hyperbolic sine of x.
func Sinh(x float64) float64 {
// The coefficients are #2029 from Hart & Cheney. (20.36D) // The coefficients are #2029 from Hart & Cheney. (20.36D)
const const
( (
@ -32,23 +32,23 @@ func Sinh(arg float64) float64 {
Q2 = -0.173678953558233699533450911e+3; Q2 = -0.173678953558233699533450911e+3;
) )
sign := false; sign := false;
if arg < 0 { if x < 0 {
arg = -arg; x = -x;
sign = true; sign = true;
} }
var temp float64; var temp float64;
switch true { switch true {
case arg > 21: case x > 21:
temp = Exp(arg)/2; temp = Exp(x)/2;
case arg > 0.5: case x > 0.5:
temp = (Exp(arg) - Exp(-arg))/2; temp = (Exp(x) - Exp(-x))/2;
default: default:
sq := arg*arg; sq := x*x;
temp = (((P3*sq+P2)*sq+P1)*sq+P0)*arg; temp = (((P3*sq+P2)*sq+P1)*sq+P0)*x;
temp = temp/(((sq+Q2)*sq+Q1)*sq+Q0); temp = temp/(((sq+Q2)*sq+Q1)*sq+Q0);
} }
@ -58,12 +58,13 @@ func Sinh(arg float64) float64 {
return temp; return temp;
} }
func Cosh(arg float64) float64 { // Cosh returns the hyperbolic cosine of x.
if arg < 0 { func Cosh(x float64) float64 {
arg = - arg; if x < 0 {
x = - x;
} }
if arg > 21 { if x > 21 {
return Exp(arg)/2; return Exp(x)/2;
} }
return (Exp(arg) + Exp(-arg))/2; return (Exp(x) + Exp(-x))/2;
} }

View file

@ -13,29 +13,35 @@ import "math"
* calls frexp * calls frexp
*/ */
func Sqrt(arg float64) float64 { // Sqrt returns the square root of x.
if IsInf(arg, 1) { //
return arg; // Special cases are:
// Sqrt(+Inf) = +Inf
// Sqrt(0) = 0
// Sqrt(x < 0) = NaN
func Sqrt(x float64) float64 {
if IsInf(x, 1) {
return x;
} }
if arg <= 0 { if x <= 0 {
if arg < 0 { if x < 0 {
return NaN(); return NaN();
} }
return 0; return 0;
} }
x,exp := Frexp(arg); y, exp := Frexp(x);
for x < 0.5 { for y < 0.5 {
x = x*2; y = y*2;
exp = exp-1; exp = exp-1;
} }
if exp&1 != 0 { if exp&1 != 0 {
x = x*2; y = y*2;
exp = exp-1; exp = exp-1;
} }
temp := 0.5 * (1+x); temp := 0.5 * (1+y);
for exp > 60 { for exp > 60 {
temp = temp * float64(1<<30); temp = temp * float64(1<<30);
@ -54,7 +60,7 @@ func Sqrt(arg float64) float64 {
} }
for i:=0; i<=4; i++ { for i:=0; i<=4; i++ {
temp = 0.5*(temp + arg/temp); temp = 0.5*(temp + x/temp);
} }
return temp; return temp;
} }

View file

@ -10,7 +10,8 @@ import "math"
* floating point tangent * floating point tangent
*/ */
func Tan(arg float64) float64 { // Tan returns the tangent of x.
func Tan(x float64) float64 {
// Coefficients are #4285 from Hart & Cheney. (19.74D) // Coefficients are #4285 from Hart & Cheney. (19.74D)
const const
( (
@ -26,7 +27,6 @@ func Tan(arg float64) float64 {
flag := false; flag := false;
sign := false; sign := false;
x := arg;
if(x < 0) { if(x < 0) {
x = -x; x = -x;
sign = true; sign = true;

View file

@ -7,23 +7,24 @@ package math
import "math" import "math"
/* /*
* tanh(arg) computes the hyperbolic tangent of its floating * tanh(x) computes the hyperbolic tangent of its floating
* point argument. * point argument.
* *
* sinh and cosh are called except for large arguments, which * sinh and cosh are called except for large arguments, which
* would cause overflow improperly. * would cause overflow improperly.
*/ */
func Tanh(arg float64) float64 { // Tanh computes the hyperbolic tangent of x.
if arg < 0 { func Tanh(x float64) float64 {
arg = -arg; if x < 0 {
if arg > 21 { x = -x;
if x > 21 {
return -1; return -1;
} }
return -Sinh(arg)/Cosh(arg); return -Sinh(x)/Cosh(x);
} }
if arg > 21 { if x > 21 {
return 1; return 1;
} }
return Sinh(arg)/Cosh(arg); return Sinh(x)/Cosh(x);
} }