summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKen Thompson <ken@golang.org>2008-03-28 13:56:47 -0700
committerKen Thompson <ken@golang.org>2008-03-28 13:56:47 -0700
commit1463bef67c5aefa2f5e6adcaef2a2a8161b27fa3 (patch)
treeaffa4befc2ba7f7e5b637b1785e46f52550da885 /src
parenteefc165c0b299d4c8206809f0c771eaccef8dc50 (diff)
downloadgolang-1463bef67c5aefa2f5e6adcaef2a2a8161b27fa3.tar.gz
SVN=114204
Diffstat (limited to 'src')
-rw-r--r--src/lib/math/asin.go60
-rw-r--r--src/lib/math/atan.go84
-rw-r--r--src/lib/math/atan2.go40
-rw-r--r--src/lib/math/exp.go54
-rw-r--r--src/lib/math/fabs.go17
-rw-r--r--src/lib/math/floor.go37
-rw-r--r--src/lib/math/fmod.go48
-rw-r--r--src/lib/math/hypot.go54
-rw-r--r--src/lib/math/log.go70
-rw-r--r--src/lib/math/main.go212
-rw-r--r--src/lib/math/math.go48
-rw-r--r--src/lib/math/pow.go70
-rw-r--r--src/lib/math/pow10.go60
-rw-r--r--src/lib/math/sin.go73
-rw-r--r--src/lib/math/sinh.go75
-rw-r--r--src/lib/math/sqrt.go64
-rw-r--r--src/lib/math/sys.go16
-rw-r--r--src/lib/math/tan.go74
-rw-r--r--src/lib/math/tanh.go32
19 files changed, 1188 insertions, 0 deletions
diff --git a/src/lib/math/asin.go b/src/lib/math/asin.go
new file mode 100644
index 000000000..6297064db
--- /dev/null
+++ b/src/lib/math/asin.go
@@ -0,0 +1,60 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package asin
+
+import sys "sys"
+import atan "atan"
+import sqrt "sqrt"
+export asin, acos
+
+/*
+ * asin(arg) and acos(arg) return the arcsin, arccos,
+ * respectively of their arguments.
+ *
+ * Arctan is called after appropriate range reduction.
+ */
+
+const
+(
+ pio2 = .15707963267948966192313216e1;
+)
+
+func
+asin(arg double)double
+{
+ var temp, x double;
+ var sign bool;
+
+ sign = false;
+ x = arg;
+ if x < 0 {
+ x = -x;
+ sign = true;
+ }
+ if arg > 1 {
+ return sys.NaN();
+ }
+
+ temp = sqrt.sqrt(1 - x*x);
+ if x > 0.7 {
+ temp = pio2 - atan.atan(temp/x);
+ } else {
+ temp = atan.atan(x/temp);
+ }
+
+ if sign {
+ temp = -temp;
+ }
+ return temp;
+}
+
+func
+acos(arg double)double
+{
+ if(arg > 1 || arg < -1) {
+ return sys.NaN();
+ }
+ return pio2 - asin(arg);
+}
diff --git a/src/lib/math/atan.go b/src/lib/math/atan.go
new file mode 100644
index 000000000..475138996
--- /dev/null
+++ b/src/lib/math/atan.go
@@ -0,0 +1,84 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package atan
+
+export atan
+
+/*
+ floating-point arctangent
+
+ atan returns the value of the arctangent of its
+ argument in the range [-pi/2,pi/2].
+ there are no error returns.
+ coefficients are #5077 from Hart & Cheney. (19.56D)
+*/
+
+
+const
+(
+ p4 = .161536412982230228262e2;
+ p3 = .26842548195503973794141e3;
+ p2 = .11530293515404850115428136e4;
+ p1 = .178040631643319697105464587e4;
+ p0 = .89678597403663861959987488e3;
+ q4 = .5895697050844462222791e2;
+ q3 = .536265374031215315104235e3;
+ q2 = .16667838148816337184521798e4;
+ q1 = .207933497444540981287275926e4;
+ q0 = .89678597403663861962481162e3;
+ pio2 = .15707963267948966192313216e1;
+ pio4 = .7853981633974483096156608e0;
+ sq2p1 = .2414213562373095048802e1; // sqrt(2)+1
+ sq2m1 = .414213562373095048802e0; // sqrt(2)-1
+)
+
+/*
+ xatan evaluates a series valid in the
+ range [-0.414...,+0.414...]. (tan(pi/8))
+ */
+
+func
+xatan(arg double) double
+{
+ var argsq, value double;
+
+ argsq = arg*arg;
+ value = ((((p4*argsq + p3)*argsq + p2)*argsq + p1)*argsq + p0);
+ value = value/(((((argsq + q4)*argsq + q3)*argsq + q2)*argsq + q1)*argsq + q0);
+ return value*arg;
+}
+
+/*
+ satan reduces its argument (known to be positive)
+ to the range [0,0.414...] and calls xatan.
+ */
+
+func
+satan(arg double) double
+{
+
+ if arg < sq2m1 {
+ return xatan(arg);
+ }
+ if arg > sq2p1 {
+ return pio2 - xatan(1/arg);
+ }
+ return pio4 + xatan((arg-1)/(arg+1));
+}
+
+/*
+ atan makes its argument positive and
+ calls the inner routine satan.
+ */
+
+func
+atan(arg double) double
+{
+
+ if arg > 0 {
+ return satan(arg);
+ }
+ return -satan(-arg);
+}
diff --git a/src/lib/math/atan2.go b/src/lib/math/atan2.go
new file mode 100644
index 000000000..2e1093f9d
--- /dev/null
+++ b/src/lib/math/atan2.go
@@ -0,0 +1,40 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package atan2
+
+import atan "atan"
+export atan2
+
+/*
+ atan2 discovers what quadrant the angle
+ is in and calls atan.
+*/
+
+const
+(
+ pio2 = .15707963267948966192313216e1;
+ pi = .3141592653589793238462643383276e1;
+)
+
+func
+atan2(arg1, arg2 double) double
+{
+ var x double;
+
+ if arg1+arg2 == arg1 {
+ if arg1 >= 0 {
+ return pio2;
+ }
+ return -pio2;
+ }
+ x = atan.atan(arg1/arg2);
+ if arg2 < 0 {
+ if x <= 0 {
+ return x + pi;
+ }
+ return x - pi;
+ }
+ return x;
+}
diff --git a/src/lib/math/exp.go b/src/lib/math/exp.go
new file mode 100644
index 000000000..8a9542a35
--- /dev/null
+++ b/src/lib/math/exp.go
@@ -0,0 +1,54 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package exp
+
+import sys "sys"
+import floor "floor"
+export exp
+
+/*
+ exp returns the exponential func of its
+ floating-point argument.
+
+ The coefficients are #1069 from Hart and Cheney. (22.35D)
+*/
+
+const
+(
+ p0 = .2080384346694663001443843411e7;
+ p1 = .3028697169744036299076048876e5;
+ p2 = .6061485330061080841615584556e2;
+ q0 = .6002720360238832528230907598e7;
+ q1 = .3277251518082914423057964422e6;
+ q2 = .1749287689093076403844945335e4;
+ log2e = .14426950408889634073599247e1;
+ sqrt2 = .14142135623730950488016887e1;
+ maxf = 10000;
+)
+
+func
+exp(arg double) double
+{
+ var x, fract, temp1, temp2, xsq double;
+ var ent int;
+
+ if arg == 0 {
+ return 1;
+ }
+ if arg < -maxf {
+ return 0;
+ }
+ if arg > maxf {
+ return sys.Inf(1);
+ }
+
+ x = arg*log2e;
+ ent = int(floor.floor(x));
+ fract = (x-double(ent)) - 0.5;
+ xsq = fract*fract;
+ temp1 = ((p2*xsq+p1)*xsq+p0)*fract;
+ temp2 = ((xsq+q2)*xsq+q1)*xsq + q0;
+ return sys.ldexp(sqrt2*(temp2+temp1)/(temp2-temp1), ent);
+}
diff --git a/src/lib/math/fabs.go b/src/lib/math/fabs.go
new file mode 100644
index 000000000..34d0de969
--- /dev/null
+++ b/src/lib/math/fabs.go
@@ -0,0 +1,17 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fabs
+
+export fabs
+
+func
+fabs(arg double) double
+{
+
+ if arg < 0 {
+ return -arg;
+ }
+ return arg;
+}
diff --git a/src/lib/math/floor.go b/src/lib/math/floor.go
new file mode 100644
index 000000000..581836a8c
--- /dev/null
+++ b/src/lib/math/floor.go
@@ -0,0 +1,37 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package floor
+
+import sys "sys"
+export floor, ceil
+
+/*
+ * floor and ceil-- greatest integer <= arg
+ * (resp least >=)
+ */
+
+func
+floor(arg double) double
+{
+ var fract, d double;
+
+ d = arg;
+ if d < 0 {
+ d,fract = sys.modf(-d);
+ if fract != 0.0 {
+ d = d+1;
+ }
+ d = -d;
+ } else {
+ d,fract = sys.modf(d);
+ }
+ return d;
+}
+
+func
+ceil(arg double) double
+{
+ return -floor(-arg);
+}
diff --git a/src/lib/math/fmod.go b/src/lib/math/fmod.go
new file mode 100644
index 000000000..fc26b5068
--- /dev/null
+++ b/src/lib/math/fmod.go
@@ -0,0 +1,48 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fmod
+
+import sys "sys"
+export fmod
+
+/*
+ floating-point mod func without infinity or NaN checking
+ */
+
+func
+fmod(x, y double) double
+{
+ var yexp, rexp int;
+ var r, yfr, rfr double;
+ var sign bool;
+
+ if y == 0 {
+ return x;
+ }
+ if y < 0 {
+ y = -y;
+ }
+
+ yexp,yfr = sys.frexp(y);
+ sign = false;
+ if x < 0 {
+ r = -x;
+ sign = true;
+ } else {
+ r = x;
+ }
+
+ for r >= y {
+ rexp,rfr = sys.frexp(r);
+ if rfr < yfr {
+ rexp = rexp - 1;
+ }
+ r = r - sys.ldexp(y, rexp-yexp);
+ }
+ if sign {
+ r = -r;
+ }
+ return r;
+}
diff --git a/src/lib/math/hypot.go b/src/lib/math/hypot.go
new file mode 100644
index 000000000..a1e9e729e
--- /dev/null
+++ b/src/lib/math/hypot.go
@@ -0,0 +1,54 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package hypot
+
+export hypot
+
+/*
+ hypot -- sqrt(p*p + q*q), but overflows only if the result does.
+ See Cleve Moler and Donald Morrison,
+ Replacing Square Roots by Pythagorean Sums
+ IBM Journal of Research and Development,
+ Vol. 27, Number 6, pp. 577-581, Nov. 1983
+ */
+
+func
+hypot(p, q double) double
+{
+ var r, s, pfac double;
+
+ if p < 0 {
+ p = -p;
+ }
+ if q < 0 {
+ q = -q;
+ }
+
+ if p < q {
+ r = p;
+ p = q;
+ q = r;
+ }
+
+ if p == 0 {
+ return 0;
+ }
+
+ pfac = p;
+ q = q/p;
+ r = q;
+ p = 1;
+ for ;; {
+ r = r*r;
+ s = r+4;
+ if s == 4 {
+ return p*pfac;
+ }
+ r = r/s;
+ p = p + 2*r*p;
+ q = q*r;
+ r = q/p;
+ }
+}
diff --git a/src/lib/math/log.go b/src/lib/math/log.go
new file mode 100644
index 000000000..cc7ebf06c
--- /dev/null
+++ b/src/lib/math/log.go
@@ -0,0 +1,70 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package log
+
+import sys "sys"
+export log, log10
+
+/*
+ log returns the natural logarithm of its floating
+ point argument.
+
+ The coefficients are #2705 from Hart & Cheney. (19.38D)
+
+ It calls frexp.
+*/
+
+const
+(
+ log2 = .693147180559945309e0;
+ ln10o1 = .4342944819032518276511;
+ sqrto2 = .707106781186547524e0;
+ p0 = -.240139179559210510e2;
+ p1 = .309572928215376501e2;
+ p2 = -.963769093377840513e1;
+ p3 = .421087371217979714e0;
+ q0 = -.120069589779605255e2;
+ q1 = .194809660700889731e2;
+ q2 = -.891110902798312337e1;
+)
+
+func
+log(arg double) double
+{
+ var x, z, zsq, temp double;
+ var exp int;
+
+ if arg <= 0 {
+ return sys.NaN();
+ }
+
+ exp,x = sys.frexp(arg);
+ for x < 0.5 {
+ x = x*2;
+ exp = exp-1;
+ }
+ if x < sqrto2 {
+ x = x*2;
+ exp = exp-1;
+ }
+
+ z = (x-1) / (x+1);
+ zsq = z*z;
+
+ temp = ((p3*zsq + p2)*zsq + p1)*zsq + p0;
+ temp = temp/(((zsq + q2)*zsq + q1)*zsq + q0);
+ temp = temp*z + double(exp)*log2;
+ return temp;
+}
+
+func
+log10(arg double) double
+{
+
+ if arg <= 0 {
+ return sys.NaN();
+ }
+ return log(arg) * ln10o1;
+}
diff --git a/src/lib/math/main.go b/src/lib/math/main.go
new file mode 100644
index 000000000..2fa7ea152
--- /dev/null
+++ b/src/lib/math/main.go
@@ -0,0 +1,212 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+
+package main
+
+import math "math"
+
+const
+(
+ length = 10;
+)
+
+var
+(
+ vf [length]double;
+ asin [length]double;
+ atan [length]double;
+ exp [length]double;
+ floor [length]double;
+ log [length]double;
+ pow [length]double;
+ sin [length]double;
+ sinh [length]double;
+ sqrt [length]double;
+ tan [length]double;
+ tanh [length]double;
+)
+
+func init();
+func ck(a,b double);
+
+func
+main()
+{
+ init();
+ for i:=0; i<length; i=i+1 {
+ f := vf[i];
+
+ ck(asin[i], math.asin(f/10));
+ ck(atan[i], math.atan(f));
+ ck(exp[i], math.exp(f));
+ ck(floor[i], math.floor(f));
+ ck(log[i], math.log(math.fabs(f)));
+ ck(pow[i], math.pow(10, f));
+ ck(sin[i], math.sin(f));
+ ck(sinh[i], math.sinh(f));
+ ck(sqrt[i], math.sqrt(math.fabs(f)));
+ ck(tan[i], math.tan(f));
+ ck(tanh[i], math.tanh(f));
+ ck(math.fabs(tanh[i]*math.sqrt(2)),
+ math.hypot(tanh[i], tanh[i]));
+ }
+}
+
+func
+ck(a,b double)
+{
+ d := a-b;
+ if d < 0 {
+ d = -d;
+ }
+
+ e := 1e-14;
+ if a != 0 {
+ e = e*a;
+ if e < 0 {
+ e = -e;
+ }
+ }
+
+ if d > e {
+ panic a, " ", b, "\n";
+ }
+}
+
+func
+init()
+{
+ vf[0] = 4.9790119248836735e+00;
+ vf[1] = 7.7388724745781045e+00;
+ vf[2] = -2.7688005719200159e-01;
+ vf[3] = -5.0106036182710749e+00;
+ vf[4] = 9.6362937071984173e+00;
+ vf[5] = 2.9263772392439646e+00;
+ vf[6] = 5.2290834314593066e+00;
+ vf[7] = 2.7279399104360102e+00;
+ vf[8] = 1.8253080916808550e+00;
+ vf[9] = -8.6859247685756013e+00;
+
+ asin[0] = 5.2117697218417440e-01;
+ asin[1] = 8.8495619865825236e-01;
+ asin[2] = -2.7691544662819413e-02;
+ asin[3] = -5.2482360935268932e-01;
+ asin[4] = 1.3002662421166553e+00;
+ asin[5] = 2.9698415875871901e-01;
+ asin[6] = 5.5025938468083364e-01;
+ asin[7] = 2.7629597861677200e-01;
+ asin[8] = 1.8355989225745148e-01;
+ asin[9] = -1.0523547536021498e+00;
+
+ atan[0] = 1.3725902621296217e+00;
+ atan[1] = 1.4422906096452980e+00;
+ atan[2] = -2.7011324359471755e-01;
+ atan[3] = -1.3738077684543379e+00;
+ atan[4] = 1.4673921193587666e+00;
+ atan[5] = 1.2415173565870167e+00;
+ atan[6] = 1.3818396865615167e+00;
+ atan[7] = 1.2194305844639670e+00;
+ atan[8] = 1.0696031952318783e+00;
+ atan[9] = -1.4561721938838085e+00;
+
+ exp[0] = 1.4533071302642137e+02;
+ exp[1] = 2.2958822575694450e+03;
+ exp[2] = 7.5814542574851664e-01;
+ exp[3] = 6.6668778421791010e-03;
+ exp[4] = 1.5310493273896035e+04;
+ exp[5] = 1.8659907517999329e+01;
+ exp[6] = 1.8662167355098713e+02;
+ exp[7] = 1.5301332413189379e+01;
+ exp[8] = 6.2047063430646876e+00;
+ exp[9] = 1.6894712385826522e-04;
+
+ floor[0] = 4.0000000000000000e+00;
+ floor[1] = 7.0000000000000000e+00;
+ floor[2] = -1.0000000000000000e+00;
+ floor[3] = -6.0000000000000000e+00;
+ floor[4] = 9.0000000000000000e+00;
+ floor[5] = 2.0000000000000000e+00;
+ floor[6] = 5.0000000000000000e+00;
+ floor[7] = 2.0000000000000000e+00;
+ floor[8] = 1.0000000000000000e+00;
+ floor[9] = -9.0000000000000000e+00;
+
+ log[0] = 1.6052314626930630e+00;
+ log[1] = 2.0462560018708768e+00;
+ log[2] = -1.2841708730962657e+00;
+ log[3] = 1.6115563905281544e+00;
+ log[4] = 2.2655365644872018e+00;
+ log[5] = 1.0737652208918380e+00;
+ log[6] = 1.6542360106073545e+00;
+ log[7] = 1.0035467127723465e+00;
+ log[8] = 6.0174879014578053e-01;
+ log[9] = 2.1617038728473527e+00;
+
+ pow[0] = 9.5282232631648415e+04;
+ pow[1] = 5.4811599352999900e+07;
+ pow[2] = 5.2859121715894400e-01;
+ pow[3] = 9.7587991957286472e-06;
+ pow[4] = 4.3280643293460450e+09;
+ pow[5] = 8.4406761805034551e+02;
+ pow[6] = 1.6946633276191194e+05;
+ pow[7] = 5.3449040147551940e+02;
+ pow[8] = 6.6881821384514159e+01;
+ pow[9] = 2.0609869004248744e-09;
+
+ sin[0] = -9.6466616586009283e-01;
+ sin[1] = 9.9338225271646543e-01;
+ sin[2] = -2.7335587039794395e-01;
+ sin[3] = 9.5586257685042800e-01;
+ sin[4] = -2.0994210667799692e-01;
+ sin[5] = 2.1355787807998605e-01;
+ sin[6] = -8.6945689711673619e-01;
+ sin[7] = 4.0195666811555783e-01;
+ sin[8] = 9.6778633541688000e-01;
+ sin[9] = -6.7344058690503452e-01;
+
+ sinh[0] = 7.2661916084208533e+01;
+ sinh[1] = 1.1479409110035194e+03;
+ sinh[2] = -2.8043136512812520e-01;
+ sinh[3] = -7.4994290911815868e+01;
+ sinh[4] = 7.6552466042906761e+03;
+ sinh[5] = 9.3031583421672010e+00;
+ sinh[6] = 9.3308157558281088e+01;
+ sinh[7] = 7.6179893137269143e+00;
+ sinh[8] = 3.0217691805496156e+00;
+ sinh[9] = -2.9595057572444951e+03;
+
+ sqrt[0] = 2.2313699659365484e+00;
+ sqrt[1] = 2.7818829009464263e+00;
+ sqrt[2] = 5.2619393496314792e-01;
+ sqrt[3] = 2.2384377628763938e+00;
+ sqrt[4] = 3.1042380236055380e+00;
+ sqrt[5] = 1.7106657298385224e+00;
+ sqrt[6] = 2.2867189227054791e+00;
+ sqrt[7] = 1.6516476350711160e+00;
+ sqrt[8] = 1.3510396336454586e+00;
+ sqrt[9] = 2.9471892997524950e+00;
+
+ tan[0] = -3.6613165650402277e+00;
+ tan[1] = 8.6490023264859754e+00;
+ tan[2] = -2.8417941955033615e-01;
+ tan[3] = 3.2532901859747287e+00;
+ tan[4] = 2.1472756403802937e-01;
+ tan[5] = -2.1860091071106700e-01;
+ tan[6] = -1.7600028178723679e+00;
+ tan[7] = -4.3898089147528178e-01;
+ tan[8] = -3.8438855602011305e+00;
+ tan[9] = 9.1098879337768517e-01;
+
+ tanh[0] = 9.9990531206936328e-01;
+ tanh[1] = 9.9999962057085307e-01;
+ tanh[2] = -2.7001505097318680e-01;
+ tanh[3] = -9.9991110943061700e-01;
+ tanh[4] = 9.9999999146798441e-01;
+ tanh[5] = 9.9427249436125233e-01;
+ tanh[6] = 9.9994257600983156e-01;
+ tanh[7] = 9.9149409509772863e-01;
+ tanh[8] = 9.4936501296239700e-01;
+ tanh[9] = -9.9999994291374019e-01;
+}
diff --git a/src/lib/math/math.go b/src/lib/math/math.go
new file mode 100644
index 000000000..9e6be9527
--- /dev/null
+++ b/src/lib/math/math.go
@@ -0,0 +1,48 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package math
+
+import
+(
+ math "asin"
+ math "atan"
+ math "atan2"
+ math "exp"
+ math "fabs"
+ math "floor"
+ math "fmod"
+ math "hypot"
+ math "log"
+ math "pow"
+ math "pow10"
+ math "sin"
+ math "sinh"
+ math "sqrt"
+ math "sys"
+ math "tan"
+ math "tanh"
+)
+
+export
+(
+ asin, acos
+ atan
+ atan2
+ exp
+ fabs
+ floor, ceil
+ fmod
+ hypot
+ log, log10
+ pow
+ pow10
+ sin, cos
+ sinh, cosh
+ sqrt
+ modf, frexp, ldexp
+ NaN, isInf, Inf
+ tan
+ tanh
+)
diff --git a/src/lib/math/pow.go b/src/lib/math/pow.go
new file mode 100644
index 000000000..b2a954fb1
--- /dev/null
+++ b/src/lib/math/pow.go
@@ -0,0 +1,70 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pow
+
+import sys "sys"
+import floor "floor"
+import sqrt "sqrt"
+import log "log"
+import exp "exp"
+export pow
+
+/*
+ arg1 ^ arg2 (exponentiation)
+ */
+
+func
+pow(arg1,arg2 double) double
+{
+ var temp double;
+ var l long;
+
+ if arg2 < 0 {
+ return 1/pow(arg1, -arg2);
+ }
+ if arg1 <= 0 {
+ if(arg1 == 0) {
+ if arg2 <= 0 {
+ return sys.NaN();
+ }
+ return 0;
+ }
+
+ temp = floor.floor(arg2);
+ if temp != arg2 {
+ return sys.NaN();
+ }
+
+ l = long(temp);
+ if l&1 != 0 {
+ return -pow(-arg1, arg2);
+ }
+ return pow(-arg1, arg2);
+ }
+
+ temp = floor.floor(arg2);
+ if temp != arg2 {
+ if arg2-temp == .5 {
+ if temp == 0 {
+ return sqrt.sqrt(arg1);
+ }
+ return pow(arg1, temp) * sqrt.sqrt(arg1);
+ }
+ return exp.exp(arg2 * log.log(arg1));
+ }
+
+ l = long(temp);
+ temp = 1;
+ for {
+ if l&1 != 0 {
+ temp = temp*arg1;
+ }
+ l = l>>1;
+ if l == 0 {
+ return temp;
+ }
+ arg1 = arg1*arg1;
+ }
+}
diff --git a/src/lib/math/pow10.go b/src/lib/math/pow10.go
new file mode 100644
index 000000000..1eb9bd1f1
--- /dev/null
+++ b/src/lib/math/pow10.go
@@ -0,0 +1,60 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pow10
+
+export pow10
+
+/*
+ * this table might overflow 127-bit exponent representations.
+ * in that case, truncate it after 1.0e38.
+ * it is important to get all one can from this
+ * routine since it is used in atof to scale numbers.
+ * the presumption is that GO converts fp numbers better
+ * than multipication of lower powers of 10.
+ */
+const
+(
+ tabsize = 70;
+)
+
+var tab[tabsize] double;
+func init();
+var initdone bool;
+
+//{
+// 1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9,
+// 1.0e10,1.0e11,1.0e12,1.0e13,1.0e14,1.0e15,1.0e16,1.0e17,1.0e18,1.0e19,
+// 1.0e20,1.0e21,1.0e22,1.0e23,1.0e24,1.0e25,1.0e26,1.0e27,1.0e28,1.0e29,
+// 1.0e30,1.0e31,1.0e32,1.0e33,1.0e34,1.0e35,1.0e36,1.0e37,1.0e38,1.0e39,
+// 1.0e40,1.0e41,1.0e42,1.0e43,1.0e44,1.0e45,1.0e46,1.0e47,1.0e48,1.0e49,
+// 1.0e50,1.0e51,1.0e52,1.0e53,1.0e54,1.0e55,1.0e56,1.0e57,1.0e58,1.0e59,
+// 1.0e60,1.0e61,1.0e62,1.0e63,1.0e64,1.0e65,1.0e66,1.0e67,1.0e68,1.0e69,
+//};
+
+func
+pow10(e int) double
+{
+ if !initdone {
+ init();
+ }
+ if e < 0 {
+ return 1/pow10(-e);
+ }
+ if e < tabsize {
+ return tab[e];
+ }
+ m := e/2;
+ return pow10(m) * pow10(e-m);
+}
+
+func
+init()
+{
+ initdone = true;
+ tab[0] = 1.0;
+ for i:=1; i<tabsize; i=i+1 {
+ tab[i] = tab[i-1]*10;
+ }
+}
diff --git a/src/lib/math/sin.go b/src/lib/math/sin.go
new file mode 100644
index 000000000..ccadd1c82
--- /dev/null
+++ b/src/lib/math/sin.go
@@ -0,0 +1,73 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sin
+
+import sys "sys"
+export sin, cos
+
+const
+(
+ p0 = .1357884097877375669092680e8;
+ p1 = -.4942908100902844161158627e7;
+ p2 = .4401030535375266501944918e6;
+ p3 = -.1384727249982452873054457e5;
+ p4 = .1459688406665768722226959e3;
+ q0 = .8644558652922534429915149e7;
+ q1 = .4081792252343299749395779e6;
+ q2 = .9463096101538208180571257e4;
+ q3 = .1326534908786136358911494e3;
+ piu2 = .6366197723675813430755350e0; // 2/pi
+)
+
+func
+sinus(arg double, quad int) double
+{
+ var e, f, ysq, x, y, temp1, temp2 double;
+ var k long;
+
+ x = arg;
+ if(x < 0) {
+ x = -x;
+ quad = quad+2;
+ }
+ x = x * piu2; /* underflow? */
+ if x > 32764 {
+ e,y = sys.modf(x);
+ e = e + double(quad);
+ temp1,f = sys.modf(0.25*e);
+ quad = int(e - 4*f);
+ } else {
+ k = long(x);
+ y = x - double(k);
+ quad = (quad + k) & 3;
+ }
+
+ if quad&1 != 0 {
+ y = 1-y;
+ }
+ if quad > 1 {
+ y = -y;
+ }
+
+ ysq = y*y;
+ temp1 = ((((p4*ysq+p3)*ysq+p2)*ysq+p1)*ysq+p0)*y;
+ temp2 = ((((ysq+q3)*ysq+q2)*ysq+q1)*ysq+q0);
+ return temp1/temp2;
+}
+
+func
+cos(arg double) double
+{
+ if arg < 0 {
+ arg = -arg;
+ }
+ return sinus(arg, 1);
+}
+
+func
+sin(arg double) double
+{
+ return sinus(arg, 0);
+}
diff --git a/src/lib/math/sinh.go b/src/lib/math/sinh.go
new file mode 100644
index 000000000..a26031ba5
--- /dev/null
+++ b/src/lib/math/sinh.go
@@ -0,0 +1,75 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sinh
+
+import exp "exp"
+export sinh, cosh
+
+/*
+ sinh(arg) returns the hyperbolic sine of its floating-
+ point argument.
+
+ The exponential func is called for arguments
+ greater in magnitude than 0.5.
+
+ A series is used for arguments smaller in magnitude than 0.5.
+ The coefficients are #2029 from Hart & Cheney. (20.36D)
+
+ cosh(arg) is computed from the exponential func for
+ all arguments.
+ */
+
+const
+(
+ p0 = -0.6307673640497716991184787251e+6;
+ p1 = -0.8991272022039509355398013511e+5;
+ p2 = -0.2894211355989563807284660366e+4;
+ p3 = -0.2630563213397497062819489e+2;
+ q0 = -0.6307673640497716991212077277e+6;
+ q1 = 0.1521517378790019070696485176e+5;
+ q2 = -0.173678953558233699533450911e+3;
+)
+
+func
+sinh(arg double) double
+{
+ var temp, argsq double;
+ var sign bool;
+
+ sign = false;
+ if arg < 0 {
+ arg = -arg;
+ sign = true;
+ }
+ switch true {
+ case arg > 21:
+ temp = exp.exp(arg)/2;
+
+ case arg > 0.5:
+ temp = (exp.exp(arg) - exp.exp(-arg))/2;
+
+ default:
+ argsq = arg*arg;
+ temp = (((p3*argsq+p2)*argsq+p1)*argsq+p0)*arg;
+ temp = temp/(((argsq+q2)*argsq+q1)*argsq+q0);
+ }
+
+ if sign {
+ temp = -temp;
+ }
+ return temp;
+}
+
+func
+cosh(arg double) double
+{
+ if arg < 0 {
+ arg = - arg;
+ }
+ if arg > 21 {
+ return exp.exp(arg)/2;
+ }
+ return (exp.exp(arg) + exp.exp(-arg))/2;
+}
diff --git a/src/lib/math/sqrt.go b/src/lib/math/sqrt.go
new file mode 100644
index 000000000..8209a3ac4
--- /dev/null
+++ b/src/lib/math/sqrt.go
@@ -0,0 +1,64 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sqrt
+
+import sys "sys"
+export sqrt
+
+/*
+ sqrt returns the square root of its floating
+ point argument. Newton's method.
+
+ calls frexp
+*/
+
+func
+sqrt(arg double) double
+{
+ var x, temp double;
+ var exp, i int;
+
+ if sys.isInf(arg, 1) {
+ return arg;
+ }
+
+ if arg <= 0 {
+ if arg < 0 {
+ return sys.NaN();
+ }
+ return 0;
+ }
+
+ exp,x = sys.frexp(arg);
+ for x < 0.5 {
+ x = x*2;
+ exp = exp-1;
+ }
+
+ if exp&1 != 0 {
+ x = x*2;
+ exp = exp-1;
+ }
+ temp = 0.5 * (1+x);
+
+ for exp > 60 {
+ temp = temp * double(1<<30);
+ exp = exp - 60;
+ }
+ for exp < -60 {
+ temp = temp / double(1<<30);
+ exp = exp + 60;
+ }
+ if exp >= 0 {
+ temp = temp * double(1 << (exp/2));
+ } else {
+ temp = temp / double(1 << (-exp/2));
+ }
+
+ for i=0; i<=4; i=i+1 {
+ temp = 0.5*(temp + arg/temp);
+ }
+ return temp;
+}
diff --git a/src/lib/math/sys.go b/src/lib/math/sys.go
new file mode 100644
index 000000000..3f7ee232a
--- /dev/null
+++ b/src/lib/math/sys.go
@@ -0,0 +1,16 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sys
+
+func modf(a double) (double, double);
+func frexp(a double) (int, double);
+func ldexp(double, int) double;
+
+func Inf(n int) double;
+func NaN() double;
+func isInf(arg double, n int) bool;
+
+export modf, frexp, ldexp
+export NaN, isInf, Inf
diff --git a/src/lib/math/tan.go b/src/lib/math/tan.go
new file mode 100644
index 000000000..913d942c2
--- /dev/null
+++ b/src/lib/math/tan.go
@@ -0,0 +1,74 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tan
+
+import sys "sys"
+export tan
+
+/*
+ floating point tangent
+ Coefficients are #4285 from Hart & Cheney. (19.74D)
+ */
+
+const
+(
+ p0 = -.1306820264754825668269611177e+5;
+ p1 = .1055970901714953193602353981e+4;
+ p2 = -.1550685653483266376941705728e+2;
+ p3 = .3422554387241003435328470489e-1;
+ p4 = .3386638642677172096076369e-4;
+ q0 = -.1663895238947119001851464661e+5;
+ q1 = .4765751362916483698926655581e+4;
+ q2 = -.1555033164031709966900124574e+3;
+ piu4 = .1273239544735162686151070107e+1; // 4/pi
+)
+
+func
+tan(arg double) double
+{
+ var temp, e, x, xsq double;
+ var i long;
+ var flag, sign bool;
+
+ flag = false;
+ sign = false;
+ x = arg;
+ if(x < 0) {
+ x = -x;
+ sign = true;
+ }
+ x = x * piu4; /* overflow? */
+ e,x = sys.modf(x);
+ i = long(e);
+
+ switch i & 3 {
+ case 1:
+ x = 1 - x;
+ flag = true;
+
+ case 2:
+ sign = !sign;
+ flag = true;
+
+ case 3:
+ x = 1 - x;
+ sign = !sign;
+ }
+
+ xsq = x*x;
+ temp = ((((p4*xsq+p3)*xsq+p2)*xsq+p1)*xsq+p0)*x;
+ temp = temp/(((xsq+q2)*xsq+q1)*xsq+q0);
+
+ if flag {
+ if(temp == 0) {
+ return sys.NaN();
+ }
+ temp = 1/temp;
+ }
+ if sign {
+ temp = -temp;
+ }
+ return temp;
+}
diff --git a/src/lib/math/tanh.go b/src/lib/math/tanh.go
new file mode 100644
index 000000000..8d1748205
--- /dev/null
+++ b/src/lib/math/tanh.go
@@ -0,0 +1,32 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tanh
+
+import sinh "sinh"
+export tanh
+
+/*
+ tanh(arg) computes the hyperbolic tangent of its floating
+ point argument.
+
+ sinh and cosh are called except for large arguments, which
+ would cause overflow improperly.
+ */
+
+func
+tanh(arg double) double
+{
+ if arg < 0 {
+ arg = -arg;
+ if arg > 21 {
+ return -1;
+ }
+ return -sinh.sinh(arg)/sinh.cosh(arg);
+ }
+ if arg > 21 {
+ return 1;
+ }
+ return sinh.sinh(arg)/sinh.cosh(arg);
+}