1
0
mirror of https://github.com/golang/go synced 2024-11-22 08:04:39 -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:
Charles L. Dorian 2010-02-10 00:06:41 -08:00 committed by Russ Cox
parent f25586a306
commit aee1434193
7 changed files with 115 additions and 0 deletions

View File

@ -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\

View File

@ -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)

View File

@ -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
View 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

View 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
View 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

View 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