]> Cypherpunks repositories - gostls13.git/commitdiff
math: add Exp2; 386 FPU versions of Exp2 and Log1p
authorCharles L. Dorian <cldorian@gmail.com>
Wed, 10 Feb 2010 08:06:41 +0000 (00:06 -0800)
committerRuss Cox <rsc@golang.org>
Wed, 10 Feb 2010 08:06:41 +0000 (00:06 -0800)
Added tests and benchmarks for Exp2 (special cases same
as Exp). Log1p also enhances speed of inverse hyperbolics.

R=rsc
CC=golang-dev
https://golang.org/cl/206058

src/pkg/math/Makefile
src/pkg/math/all_test.go
src/pkg/math/exp.go
src/pkg/math/exp2_386.s [new file with mode: 0644]
src/pkg/math/exp2_decl.go [new file with mode: 0644]
src/pkg/math/log1p_386.s [new file with mode: 0644]
src/pkg/math/log1p_decl.go [new file with mode: 0644]

index 97c5af1b8a15ed12da10eca7896099976e5a2809..6657724c2ae1f98723b8f10b2f633db50fa8c8b7 100644 (file)
@@ -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\
index 8c47fd1cf3f67d9ff5587ecdc22bbfe6cec944a3..bd1d4006a819bc91603ee96def10ca82054cd40d 100644 (file)
@@ -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)
index 5ea58c0fb391d302d285745e3c42f6015e0c069f..18ec684dfa7a250e38695c97a3e95f779b5e258a 100644 (file)
@@ -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 (file)
index 0000000..ed82a4d
--- /dev/null
@@ -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 (file)
index 0000000..cff7411
--- /dev/null
@@ -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 (file)
index 0000000..30df88e
--- /dev/null
@@ -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 (file)
index 0000000..84b6030
--- /dev/null
@@ -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