Commit dfc3910a authored by Russ Cox's avatar Russ Cox

math: doc

R=r
DELTA=173  (74 added, 14 deleted, 85 changed)
OCL=25753
CL=25767
parent 83de0698
...@@ -13,21 +13,18 @@ import "math" ...@@ -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 { ...@@ -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);
} }
...@@ -57,9 +57,11 @@ func satan(arg float64) float64 { ...@@ -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);
} }
...@@ -6,23 +6,23 @@ package math ...@@ -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;
} }
...@@ -2,12 +2,12 @@ ...@@ -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 ( ...@@ -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.
...@@ -82,6 +82,13 @@ import "math" ...@@ -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;
......
...@@ -4,10 +4,11 @@ ...@@ -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;
} }
...@@ -6,23 +6,20 @@ package math ...@@ -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);
} }
...@@ -10,6 +10,7 @@ import "math" ...@@ -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;
......
...@@ -12,6 +12,8 @@ package math ...@@ -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;
......
...@@ -70,6 +70,13 @@ import "math" ...@@ -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 { ...@@ -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);
} }
...@@ -6,7 +6,7 @@ package math ...@@ -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 {
......
...@@ -15,6 +15,7 @@ package math ...@@ -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);
......
...@@ -7,14 +7,46 @@ package math ...@@ -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.
// Float32bits returns the IEEE 754 binary representation of f.
func Float32bits(f float32) (b uint32) func Float32bits(f float32) (b uint32)
// Float32frombits returns the floating point number corresponding
// to the IEEE 754 binary representation b.
func Float32frombits(b uint32) (f float32) func Float32frombits(b uint32) (f float32)
// Float64bits returns the IEEE 754 binary representation of f.
func Float64bits(f float64) (b uint64) func Float64bits(f float64) (b uint64)
// Float64frombits returns the floating point number corresponding
// the IEEE 754 binary representation b.
func Float64frombits(b uint64) (f float64) 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) 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) 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) 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) 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) 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) func Modf(f float64) (integer float64, frac float64)
// NaN returns an IEEE 754 ``not-a-number'' value.
func NaN() (f float64) func NaN() (f float64)
...@@ -6,7 +6,7 @@ package math ...@@ -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 { ...@@ -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 { ...@@ -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);
} }
...@@ -7,19 +7,19 @@ package math ...@@ -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
( (
...@@ -33,22 +33,22 @@ func Sinh(arg float64) float64 { ...@@ -33,22 +33,22 @@ func Sinh(arg float64) float64 {
) )
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 { ...@@ -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;
} }
...@@ -13,29 +13,35 @@ import "math" ...@@ -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 { ...@@ -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;
} }
...@@ -10,7 +10,8 @@ import "math" ...@@ -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 { ...@@ -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;
......
...@@ -7,23 +7,24 @@ package math ...@@ -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);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment