summaryrefslogtreecommitdiff
path: root/src/pkg/math
diff options
context:
space:
mode:
authorCharles L. Dorian <cldorian@gmail.com>2010-02-10 00:06:41 -0800
committerCharles L. Dorian <cldorian@gmail.com>2010-02-10 00:06:41 -0800
commit7086ba674c743e12521b3cbfb3d2b5e1a3469c11 (patch)
tree11b9b54514e379bb98f60ba77cce3124c9fa29c4 /src/pkg/math
parent6ee4537544fe3176118be01a9349d6525d41c114 (diff)
downloadgolang-7086ba674c743e12521b3cbfb3d2b5e1a3469c11.tar.gz
math: add Exp2; 386 FPU versions of Exp2 and Log1p
Added tests and benchmarks for Exp2 (special cases same as Exp). Log1p also enhances speed of inverse hyperbolics. R=rsc CC=golang-dev http://codereview.appspot.com/206058 Committer: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/pkg/math')
-rw-r--r--src/pkg/math/Makefile2
-rw-r--r--src/pkg/math/all_test.go31
-rw-r--r--src/pkg/math/exp.go5
-rw-r--r--src/pkg/math/exp2_386.s38
-rw-r--r--src/pkg/math/exp2_decl.go7
-rw-r--r--src/pkg/math/log1p_386.s25
-rw-r--r--src/pkg/math/log1p_decl.go7
7 files changed, 115 insertions, 0 deletions
diff --git a/src/pkg/math/Makefile b/src/pkg/math/Makefile
index 97c5af1b8..6657724c2 100644
--- a/src/pkg/math/Makefile
+++ b/src/pkg/math/Makefile
@@ -14,11 +14,13 @@ OFILES_386=\
atan_386.$O\
atan2_386.$O\
exp_386.$O\
+ exp2_386.$O\
fabs_386.$O\
floor_386.$O\
fmod_386.$O\
hypot_386.$O\
log_386.$O\
+ log1p_386.$O\
modf_386.$O\
sin_386.$O\
sqrt_386.$O\
diff --git a/src/pkg/math/all_test.go b/src/pkg/math/all_test.go
index 8c47fd1cf..bd1d4006a 100644
--- a/src/pkg/math/all_test.go
+++ b/src/pkg/math/all_test.go
@@ -208,6 +208,18 @@ var expm1 = []float64{
1.842068661871398836913874273e-02,
-8.3193870863553801814961137573e-02,
}
+var exp2 = []float64{
+ 3.1537839463286288034313104e+01,
+ 2.1361549283756232296144849e+02,
+ 8.2537402562185562902577219e-01,
+ 3.1021158628740294833424229e-02,
+ 7.9581744110252191462569661e+02,
+ 7.6019905892596359262696423e+00,
+ 3.7506882048388096973183084e+01,
+ 6.6250893439173561733216375e+00,
+ 3.5438267900243941544605339e+00,
+ 2.4281533133513300984289196e-03,
+}
var fdim = []float64{
4.9790119248836735e+00,
7.7388724745781045e+00,
@@ -1078,6 +1090,19 @@ func TestExpm1(t *testing.T) {
}
}
+func TestExp2(t *testing.T) {
+ for i := 0; i < len(vf); i++ {
+ if f := Exp2(vf[i]); !close(exp2[i], f) {
+ t.Errorf("Exp2(%g) = %g, want %g\n", vf[i], f, exp2[i])
+ }
+ }
+ for i := 0; i < len(vfexpSC); i++ {
+ if f := Exp2(vfexpSC[i]); !alike(expSC[i], f) {
+ t.Errorf("Exp2(%g) = %g, want %g\n", vfexpSC[i], f, expSC[i])
+ }
+ }
+}
+
func TestFdim(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Fdim(vf[i], 0); fdim[i] != f {
@@ -1492,6 +1517,12 @@ func BenchmarkExpm1(b *testing.B) {
}
}
+func BenchmarkExp2(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ Exp(.5)
+ }
+}
+
func BenchmarkFloor(b *testing.B) {
for i := 0; i < b.N; i++ {
Floor(.5)
diff --git a/src/pkg/math/exp.go b/src/pkg/math/exp.go
index 5ea58c0fb..18ec684df 100644
--- a/src/pkg/math/exp.go
+++ b/src/pkg/math/exp.go
@@ -139,3 +139,8 @@ func Exp(x float64) float64 {
// TODO(rsc): make sure Ldexp can handle boundary k
return Ldexp(y, k)
}
+
+// Exp2 returns 2^x, the base-2 exponential of x.
+//
+// Special cases are the same as Exp.
+func Exp2(x float64) float64 { return Exp(x * Ln2) }
diff --git a/src/pkg/math/exp2_386.s b/src/pkg/math/exp2_386.s
new file mode 100644
index 000000000..ed82a4dd3
--- /dev/null
+++ b/src/pkg/math/exp2_386.s
@@ -0,0 +1,38 @@
+// Copyright 2010 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.
+
+// func Exp2(x float64) float64
+TEXT ·Exp2(SB),7,$0
+// test bits for not-finite
+ MOVL x+4(FP), AX
+ ANDL $0x7ff00000, AX
+ CMPL AX, $0x7ff00000
+ JEQ not_finite
+ FMOVD x+0(FP), F0 // F0=x
+ FMOVD F0, F1 // F0=x, F1=x
+ FRNDINT // F0=int(x), F1=x
+ FSUBD F0, F1 // F0=int(x), F1=x-int(x)
+ FXCHD F0, F1 // F0=x-int(x), F1=int(x)
+ F2XM1 // F0=2**(x-int(x))-1, F1=int(x)
+ FLD1 // F0=1, F1=2**(x-int(x))-1, F2=int(x)
+ FADDDP F0, F1 // F0=2**(x-int(x)), F1=int(x)
+ FSCALE // F0=2**x, F1=int(x)
+ FMOVDP F0, F1 // F0=2**x
+ FMOVDP F0, r+8(FP)
+ RET
+not_finite:
+// test bits for -Inf
+ MOVL x+4(FP), BX
+ MOVL x+0(FP), CX
+ CMPL BX, $0xfff00000
+ JNE not_neginf
+ CMPL CX, $0
+ JNE not_neginf
+ MOVL $0, r+8(FP)
+ MOVL $0, r+12(FP)
+ RET
+not_neginf:
+ MOVL CX, r+8(FP)
+ MOVL BX, r+12(FP)
+ RET
diff --git a/src/pkg/math/exp2_decl.go b/src/pkg/math/exp2_decl.go
new file mode 100644
index 000000000..cff741174
--- /dev/null
+++ b/src/pkg/math/exp2_decl.go
@@ -0,0 +1,7 @@
+// Copyright 2010 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
+
+func Exp2(x float64) float64
diff --git a/src/pkg/math/log1p_386.s b/src/pkg/math/log1p_386.s
new file mode 100644
index 000000000..30df88e1f
--- /dev/null
+++ b/src/pkg/math/log1p_386.s
@@ -0,0 +1,25 @@
+// Copyright 2010 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.
+
+// func Log1p(x float64) float64
+TEXT ·Log1p(SB),7,$0
+ FMOVD $(2.928932188134524e-01), F0
+ FMOVD x+0(FP), F0 // F0=x, F1=1-sqrt(2)/2 = 0.29289321881345247559915564
+ FABS // F0=|x|, F1=1-sqrt(2)/2
+ FUCOMPP F0, F1 // compare F0 to F1
+ FSTSW AX
+ FLDLN2 // F0=log(2)
+ ANDW $0x0100, AX
+ JEQ use_fyl2x // jump if F0 >= F1
+ FMOVD x+0(FP), F0 // F0=x, F1=log(2)
+ FYL2XP1 // F0=log(1+x)=log2(1+x)*log(2)
+ FMOVDP F0, r+8(FP)
+ RET
+use_fyl2x:
+ FLD1 // F0=1, F2=log(2)
+ FADDD x+0(FP), F0 // F0=1+x, F1=log(2)
+ FYL2X // F0=log(1+x)=log2(1+x)*log(2)
+ FMOVDP F0, r+8(FP)
+ RET
+
diff --git a/src/pkg/math/log1p_decl.go b/src/pkg/math/log1p_decl.go
new file mode 100644
index 000000000..84b6030fb
--- /dev/null
+++ b/src/pkg/math/log1p_decl.go
@@ -0,0 +1,7 @@
+// Copyright 2010 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
+
+func Log1p(x float64) float64