diff options
author | Charles L. Dorian <cldorian@gmail.com> | 2010-02-10 00:06:41 -0800 |
---|---|---|
committer | Charles L. Dorian <cldorian@gmail.com> | 2010-02-10 00:06:41 -0800 |
commit | 7086ba674c743e12521b3cbfb3d2b5e1a3469c11 (patch) | |
tree | 11b9b54514e379bb98f60ba77cce3124c9fa29c4 /src/pkg/math | |
parent | 6ee4537544fe3176118be01a9349d6525d41c114 (diff) | |
download | golang-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/Makefile | 2 | ||||
-rw-r--r-- | src/pkg/math/all_test.go | 31 | ||||
-rw-r--r-- | src/pkg/math/exp.go | 5 | ||||
-rw-r--r-- | src/pkg/math/exp2_386.s | 38 | ||||
-rw-r--r-- | src/pkg/math/exp2_decl.go | 7 | ||||
-rw-r--r-- | src/pkg/math/log1p_386.s | 25 | ||||
-rw-r--r-- | src/pkg/math/log1p_decl.go | 7 |
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 |