mirror of
https://github.com/golang/go
synced 2024-11-22 08:14:40 -07:00
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 https://golang.org/cl/206058
This commit is contained in:
parent
f25586a306
commit
aee1434193
@ -14,11 +14,13 @@ OFILES_386=\
|
|||||||
atan_386.$O\
|
atan_386.$O\
|
||||||
atan2_386.$O\
|
atan2_386.$O\
|
||||||
exp_386.$O\
|
exp_386.$O\
|
||||||
|
exp2_386.$O\
|
||||||
fabs_386.$O\
|
fabs_386.$O\
|
||||||
floor_386.$O\
|
floor_386.$O\
|
||||||
fmod_386.$O\
|
fmod_386.$O\
|
||||||
hypot_386.$O\
|
hypot_386.$O\
|
||||||
log_386.$O\
|
log_386.$O\
|
||||||
|
log1p_386.$O\
|
||||||
modf_386.$O\
|
modf_386.$O\
|
||||||
sin_386.$O\
|
sin_386.$O\
|
||||||
sqrt_386.$O\
|
sqrt_386.$O\
|
||||||
|
@ -208,6 +208,18 @@ var expm1 = []float64{
|
|||||||
1.842068661871398836913874273e-02,
|
1.842068661871398836913874273e-02,
|
||||||
-8.3193870863553801814961137573e-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{
|
var fdim = []float64{
|
||||||
4.9790119248836735e+00,
|
4.9790119248836735e+00,
|
||||||
7.7388724745781045e+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) {
|
func TestFdim(t *testing.T) {
|
||||||
for i := 0; i < len(vf); i++ {
|
for i := 0; i < len(vf); i++ {
|
||||||
if f := Fdim(vf[i], 0); fdim[i] != f {
|
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) {
|
func BenchmarkFloor(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
Floor(.5)
|
Floor(.5)
|
||||||
|
@ -139,3 +139,8 @@ func Exp(x float64) float64 {
|
|||||||
// TODO(rsc): make sure Ldexp can handle boundary k
|
// TODO(rsc): make sure Ldexp can handle boundary k
|
||||||
return Ldexp(y, 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) }
|
||||||
|
38
src/pkg/math/exp2_386.s
Normal file
38
src/pkg/math/exp2_386.s
Normal file
@ -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
|
7
src/pkg/math/exp2_decl.go
Normal file
7
src/pkg/math/exp2_decl.go
Normal file
@ -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
|
25
src/pkg/math/log1p_386.s
Normal file
25
src/pkg/math/log1p_386.s
Normal file
@ -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
|
||||||
|
|
7
src/pkg/math/log1p_decl.go
Normal file
7
src/pkg/math/log1p_decl.go
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user