summaryrefslogtreecommitdiff
path: root/src/pkg/math
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-01-17 12:40:45 +0100
committerOndřej Surý <ondrej@sury.org>2011-01-17 12:40:45 +0100
commit3e45412327a2654a77944249962b3652e6142299 (patch)
treebc3bf69452afa055423cbe0c5cfa8ca357df6ccf /src/pkg/math
parentc533680039762cacbc37db8dc7eed074c3e497be (diff)
downloadgolang-upstream/2011.01.12.tar.gz
Imported Upstream version 2011.01.12upstream/2011.01.12
Diffstat (limited to 'src/pkg/math')
-rw-r--r--src/pkg/math/Makefile10
-rw-r--r--src/pkg/math/all_test.go700
-rw-r--r--src/pkg/math/bits.go2
-rw-r--r--src/pkg/math/const.go10
-rw-r--r--src/pkg/math/exp.go129
-rw-r--r--src/pkg/math/exp2.go2
-rw-r--r--src/pkg/math/exp_amd64.s92
-rw-r--r--src/pkg/math/exp_port.go192
-rw-r--r--src/pkg/math/exp_test.go10
-rw-r--r--src/pkg/math/frexp.go4
-rw-r--r--src/pkg/math/hypot_amd64.s50
-rw-r--r--src/pkg/math/log.go8
-rw-r--r--src/pkg/math/log10.go13
-rw-r--r--src/pkg/math/log10_386.s19
-rw-r--r--src/pkg/math/log10_decl.go8
-rw-r--r--src/pkg/math/log_386.s16
-rw-r--r--src/pkg/math/log_amd64.s109
-rw-r--r--src/pkg/math/log_decl.go2
-rw-r--r--src/pkg/math/logb.go4
-rw-r--r--src/pkg/math/modf.go6
-rw-r--r--src/pkg/math/sincos_amd64.s143
-rw-r--r--src/pkg/math/sqrt_port.go4
-rw-r--r--src/pkg/math/tan.go2
23 files changed, 995 insertions, 540 deletions
diff --git a/src/pkg/math/Makefile b/src/pkg/math/Makefile
index a2d11e43d..71347b7fa 100644
--- a/src/pkg/math/Makefile
+++ b/src/pkg/math/Makefile
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
-include ../../Make.$(GOARCH)
+include ../../Make.inc
TARG=math
@@ -10,6 +10,9 @@ OFILES_amd64=\
exp_amd64.$O\
fabs_amd64.$O\
fdim_amd64.$O\
+ hypot_amd64.$O\
+ log_amd64.$O\
+ sincos_amd64.$O\
sqrt_amd64.$O\
OFILES_386=\
@@ -26,6 +29,7 @@ OFILES_386=\
hypot_386.$O\
ldexp_386.$O\
log_386.$O\
+ log10_386.$O\
log1p_386.$O\
modf_386.$O\
remainder_386.$O\
@@ -50,6 +54,7 @@ ALLGOFILES=\
copysign.go\
erf.go\
exp.go\
+ exp_port.go\
exp2.go\
expm1.go\
fabs.go\
@@ -63,11 +68,12 @@ ALLGOFILES=\
j0.go\
j1.go\
jn.go\
- logb.go\
lgamma.go\
ldexp.go\
log.go\
+ log10.go\
log1p.go\
+ logb.go\
modf.go\
nextafter.go\
pow.go\
diff --git a/src/pkg/math/all_test.go b/src/pkg/math/all_test.go
index 18a3f1b31..6033d37e3 100644
--- a/src/pkg/math/all_test.go
+++ b/src/pkg/math/all_test.go
@@ -7,6 +7,7 @@ package math_test
import (
"fmt"
. "math"
+ "runtime"
"testing"
)
@@ -286,16 +287,16 @@ type fi struct {
}
var frexp = []fi{
- fi{6.2237649061045918750e-01, 3},
- fi{9.6735905932226306250e-01, 3},
- fi{-5.5376011438400318000e-01, -1},
- fi{-6.2632545228388436250e-01, 3},
- fi{6.02268356699901081250e-01, 4},
- fi{7.3159430981099115000e-01, 2},
- fi{6.5363542893241332500e-01, 3},
- fi{6.8198497760900255000e-01, 2},
- fi{9.1265404584042750000e-01, 1},
- fi{-5.4287029803597508250e-01, 4},
+ {6.2237649061045918750e-01, 3},
+ {9.6735905932226306250e-01, 3},
+ {-5.5376011438400318000e-01, -1},
+ {-6.2632545228388436250e-01, 3},
+ {6.02268356699901081250e-01, 4},
+ {7.3159430981099115000e-01, 2},
+ {6.5363542893241332500e-01, 3},
+ {6.8198497760900255000e-01, 2},
+ {9.1265404584042750000e-01, 1},
+ {-5.4287029803597508250e-01, 4},
}
var gamma = []float64{
2.3254348370739963835386613898e+01,
@@ -358,16 +359,16 @@ var jM3 = []float64{
-2.3762660886100206491674503e-01,
}
var lgamma = []fi{
- fi{3.146492141244545774319734e+00, 1},
- fi{8.003414490659126375852113e+00, 1},
- fi{1.517575735509779707488106e+00, -1},
- fi{-2.588480028182145853558748e-01, 1},
- fi{1.1989897050205555002007985e+01, 1},
- fi{6.262899811091257519386906e-01, 1},
- fi{3.5287924899091566764846037e+00, 1},
- fi{4.5725644770161182299423372e-01, 1},
- fi{-6.363667087767961257654854e-02, 1},
- fi{-1.077385130910300066425564e+01, -1},
+ {3.146492141244545774319734e+00, 1},
+ {8.003414490659126375852113e+00, 1},
+ {1.517575735509779707488106e+00, -1},
+ {-2.588480028182145853558748e-01, 1},
+ {1.1989897050205555002007985e+01, 1},
+ {6.262899811091257519386906e-01, 1},
+ {3.5287924899091566764846037e+00, 1},
+ {4.5725644770161182299423372e-01, 1},
+ {-6.363667087767961257654854e-02, 1},
+ {-1.077385130910300066425564e+01, -1},
}
var log = []float64{
1.605231462693062999102599e+00,
@@ -382,16 +383,16 @@ var log = []float64{
2.161703872847352815363655e+00,
}
var logb = []float64{
- 3.0000000000000000e+00,
- 3.0000000000000000e+00,
- -1.0000000000000000e+00,
- 3.0000000000000000e+00,
- 4.0000000000000000e+00,
+ 2.0000000000000000e+00,
+ 2.0000000000000000e+00,
+ -2.0000000000000000e+00,
2.0000000000000000e+00,
3.0000000000000000e+00,
+ 1.0000000000000000e+00,
2.0000000000000000e+00,
1.0000000000000000e+00,
- 4.0000000000000000e+00,
+ 0.0000000000000000e+00,
+ 3.0000000000000000e+00,
}
var log10 = []float64{
6.9714316642508290997617083e-01,
@@ -430,16 +431,16 @@ var log2 = []float64{
3.118679457227342224364709e+00,
}
var modf = [][2]float64{
- [2]float64{4.0000000000000000e+00, 9.7901192488367350108546816e-01},
- [2]float64{7.0000000000000000e+00, 7.3887247457810456552351752e-01},
- [2]float64{0.0000000000000000e+00, -2.7688005719200159404635997e-01},
- [2]float64{-5.0000000000000000e+00, -1.060361827107492160848778e-02},
- [2]float64{9.0000000000000000e+00, 6.3629370719841737980004837e-01},
- [2]float64{2.0000000000000000e+00, 9.2637723924396464525443662e-01},
- [2]float64{5.0000000000000000e+00, 2.2908343145930665230025625e-01},
- [2]float64{2.0000000000000000e+00, 7.2793991043601025126008608e-01},
- [2]float64{1.0000000000000000e+00, 8.2530809168085506044576505e-01},
- [2]float64{-8.0000000000000000e+00, -6.8592476857560136238589621e-01},
+ {4.0000000000000000e+00, 9.7901192488367350108546816e-01},
+ {7.0000000000000000e+00, 7.3887247457810456552351752e-01},
+ {0.0000000000000000e+00, -2.7688005719200159404635997e-01},
+ {-5.0000000000000000e+00, -1.060361827107492160848778e-02},
+ {9.0000000000000000e+00, 6.3629370719841737980004837e-01},
+ {2.0000000000000000e+00, 9.2637723924396464525443662e-01},
+ {5.0000000000000000e+00, 2.2908343145930665230025625e-01},
+ {2.0000000000000000e+00, 7.2793991043601025126008608e-01},
+ {1.0000000000000000e+00, 8.2530809168085506044576505e-01},
+ {-8.0000000000000000e+00, -6.8592476857560136238589621e-01},
}
var nextafter = []float64{
4.97901192488367438926388786e+00,
@@ -707,41 +708,41 @@ var atanhSC = []float64{
NaN(),
}
var vfatan2SC = [][2]float64{
- [2]float64{Inf(-1), Inf(-1)},
- [2]float64{Inf(-1), -Pi},
- [2]float64{Inf(-1), 0},
- [2]float64{Inf(-1), +Pi},
- [2]float64{Inf(-1), Inf(1)},
- [2]float64{Inf(-1), NaN()},
- [2]float64{-Pi, Inf(-1)},
- [2]float64{-Pi, 0},
- [2]float64{-Pi, Inf(1)},
- [2]float64{-Pi, NaN()},
- [2]float64{Copysign(0, -1), Inf(-1)},
- [2]float64{Copysign(0, -1), -Pi},
- [2]float64{Copysign(0, -1), Copysign(0, -1)},
- [2]float64{Copysign(0, -1), 0},
- [2]float64{Copysign(0, -1), +Pi},
- [2]float64{Copysign(0, -1), Inf(1)},
- [2]float64{Copysign(0, -1), NaN()},
- [2]float64{0, Inf(-1)},
- [2]float64{0, -Pi},
- [2]float64{0, Copysign(0, -1)},
- [2]float64{0, 0},
- [2]float64{0, +Pi},
- [2]float64{0, Inf(1)},
- [2]float64{0, NaN()},
- [2]float64{+Pi, Inf(-1)},
- [2]float64{+Pi, 0},
- [2]float64{+Pi, Inf(1)},
- [2]float64{+Pi, NaN()},
- [2]float64{Inf(1), Inf(-1)},
- [2]float64{Inf(1), -Pi},
- [2]float64{Inf(1), 0},
- [2]float64{Inf(1), +Pi},
- [2]float64{Inf(1), Inf(1)},
- [2]float64{Inf(1), NaN()},
- [2]float64{NaN(), NaN()},
+ {Inf(-1), Inf(-1)},
+ {Inf(-1), -Pi},
+ {Inf(-1), 0},
+ {Inf(-1), +Pi},
+ {Inf(-1), Inf(1)},
+ {Inf(-1), NaN()},
+ {-Pi, Inf(-1)},
+ {-Pi, 0},
+ {-Pi, Inf(1)},
+ {-Pi, NaN()},
+ {Copysign(0, -1), Inf(-1)},
+ {Copysign(0, -1), -Pi},
+ {Copysign(0, -1), Copysign(0, -1)},
+ {Copysign(0, -1), 0},
+ {Copysign(0, -1), +Pi},
+ {Copysign(0, -1), Inf(1)},
+ {Copysign(0, -1), NaN()},
+ {0, Inf(-1)},
+ {0, -Pi},
+ {0, Copysign(0, -1)},
+ {0, 0},
+ {0, +Pi},
+ {0, Inf(1)},
+ {0, NaN()},
+ {+Pi, Inf(-1)},
+ {+Pi, 0},
+ {+Pi, Inf(1)},
+ {+Pi, NaN()},
+ {Inf(1), Inf(-1)},
+ {Inf(1), -Pi},
+ {Inf(1), 0},
+ {Inf(1), +Pi},
+ {Inf(1), Inf(1)},
+ {Inf(1), NaN()},
+ {NaN(), NaN()},
}
var atan2SC = []float64{
-3 * Pi / 4, // atan2(-Inf, -Inf)
@@ -876,11 +877,15 @@ var erfcSC = []float64{
var vfexpSC = []float64{
Inf(-1),
+ -2000,
+ 2000,
Inf(1),
NaN(),
}
var expSC = []float64{
0,
+ 0,
+ Inf(1),
Inf(1),
NaN(),
}
@@ -916,40 +921,40 @@ var fabsSC = []float64{
}
var vffmodSC = [][2]float64{
- [2]float64{Inf(-1), Inf(-1)},
- [2]float64{Inf(-1), -Pi},
- [2]float64{Inf(-1), 0},
- [2]float64{Inf(-1), Pi},
- [2]float64{Inf(-1), Inf(1)},
- [2]float64{Inf(-1), NaN()},
- [2]float64{-Pi, Inf(-1)},
- [2]float64{-Pi, 0},
- [2]float64{-Pi, Inf(1)},
- [2]float64{-Pi, NaN()},
- [2]float64{Copysign(0, -1), Inf(-1)},
- [2]float64{Copysign(0, -1), 0},
- [2]float64{Copysign(0, -1), Inf(1)},
- [2]float64{Copysign(0, -1), NaN()},
- [2]float64{0, Inf(-1)},
- [2]float64{0, 0},
- [2]float64{0, Inf(1)},
- [2]float64{0, NaN()},
- [2]float64{Pi, Inf(-1)},
- [2]float64{Pi, 0},
- [2]float64{Pi, Inf(1)},
- [2]float64{Pi, NaN()},
- [2]float64{Inf(1), Inf(-1)},
- [2]float64{Inf(1), -Pi},
- [2]float64{Inf(1), 0},
- [2]float64{Inf(1), Pi},
- [2]float64{Inf(1), Inf(1)},
- [2]float64{Inf(1), NaN()},
- [2]float64{NaN(), Inf(-1)},
- [2]float64{NaN(), -Pi},
- [2]float64{NaN(), 0},
- [2]float64{NaN(), Pi},
- [2]float64{NaN(), Inf(1)},
- [2]float64{NaN(), NaN()},
+ {Inf(-1), Inf(-1)},
+ {Inf(-1), -Pi},
+ {Inf(-1), 0},
+ {Inf(-1), Pi},
+ {Inf(-1), Inf(1)},
+ {Inf(-1), NaN()},
+ {-Pi, Inf(-1)},
+ {-Pi, 0},
+ {-Pi, Inf(1)},
+ {-Pi, NaN()},
+ {Copysign(0, -1), Inf(-1)},
+ {Copysign(0, -1), 0},
+ {Copysign(0, -1), Inf(1)},
+ {Copysign(0, -1), NaN()},
+ {0, Inf(-1)},
+ {0, 0},
+ {0, Inf(1)},
+ {0, NaN()},
+ {Pi, Inf(-1)},
+ {Pi, 0},
+ {Pi, Inf(1)},
+ {Pi, NaN()},
+ {Inf(1), Inf(-1)},
+ {Inf(1), -Pi},
+ {Inf(1), 0},
+ {Inf(1), Pi},
+ {Inf(1), Inf(1)},
+ {Inf(1), NaN()},
+ {NaN(), Inf(-1)},
+ {NaN(), -Pi},
+ {NaN(), 0},
+ {NaN(), Pi},
+ {NaN(), Inf(1)},
+ {NaN(), NaN()},
}
var fmodSC = []float64{
NaN(), // fmod(-Inf, -Inf)
@@ -996,11 +1001,11 @@ var vffrexpSC = []float64{
NaN(),
}
var frexpSC = []fi{
- fi{Inf(-1), 0},
- fi{Copysign(0, -1), 0},
- fi{0, 0},
- fi{Inf(1), 0},
- fi{NaN(), 0},
+ {Inf(-1), 0},
+ {Copysign(0, -1), 0},
+ {0, 0},
+ {Inf(1), 0},
+ {NaN(), 0},
}
var vfgammaSC = []float64{
@@ -1021,25 +1026,25 @@ var gammaSC = []float64{
}
var vfhypotSC = [][2]float64{
- [2]float64{Inf(-1), Inf(-1)},
- [2]float64{Inf(-1), 0},
- [2]float64{Inf(-1), Inf(1)},
- [2]float64{Inf(-1), NaN()},
- [2]float64{Copysign(0, -1), Copysign(0, -1)},
- [2]float64{Copysign(0, -1), 0},
- [2]float64{0, Copysign(0, -1)},
- [2]float64{0, 0}, // +0, +0
- [2]float64{0, Inf(-1)},
- [2]float64{0, Inf(1)},
- [2]float64{0, NaN()},
- [2]float64{Inf(1), Inf(-1)},
- [2]float64{Inf(1), 0},
- [2]float64{Inf(1), Inf(1)},
- [2]float64{Inf(1), NaN()},
- [2]float64{NaN(), Inf(-1)},
- [2]float64{NaN(), 0},
- [2]float64{NaN(), Inf(1)},
- [2]float64{NaN(), NaN()},
+ {Inf(-1), Inf(-1)},
+ {Inf(-1), 0},
+ {Inf(-1), Inf(1)},
+ {Inf(-1), NaN()},
+ {Copysign(0, -1), Copysign(0, -1)},
+ {Copysign(0, -1), 0},
+ {0, Copysign(0, -1)},
+ {0, 0}, // +0, +0
+ {0, Inf(-1)},
+ {0, Inf(1)},
+ {0, NaN()},
+ {Inf(1), Inf(-1)},
+ {Inf(1), 0},
+ {Inf(1), Inf(1)},
+ {Inf(1), NaN()},
+ {NaN(), Inf(-1)},
+ {NaN(), 0},
+ {NaN(), Inf(1)},
+ {NaN(), NaN()},
}
var hypotSC = []float64{
Inf(1),
@@ -1117,13 +1122,13 @@ var vflgammaSC = []float64{
NaN(),
}
var lgammaSC = []fi{
- fi{Inf(-1), 1},
- fi{Inf(1), 1},
- fi{Inf(1), 1},
- fi{0, 1},
- fi{0, 1},
- fi{Inf(1), 1},
- fi{NaN(), 1},
+ {Inf(-1), 1},
+ {Inf(1), 1},
+ {Inf(1), 1},
+ {0, 1},
+ {0, 1},
+ {Inf(1), 1},
+ {NaN(), 1},
}
var vflogSC = []float64{
@@ -1183,15 +1188,15 @@ var vfmodfSC = []float64{
NaN(),
}
var modfSC = [][2]float64{
- [2]float64{Inf(-1), NaN()}, // [2]float64{Copysign(0, -1), Inf(-1)},
- [2]float64{Inf(1), NaN()}, // [2]float64{0, Inf(1)},
- [2]float64{NaN(), NaN()},
+ {Inf(-1), NaN()}, // [2]float64{Copysign(0, -1), Inf(-1)},
+ {Inf(1), NaN()}, // [2]float64{0, Inf(1)},
+ {NaN(), NaN()},
}
var vfnextafterSC = [][2]float64{
- [2]float64{0, NaN()},
- [2]float64{NaN(), 0},
- [2]float64{NaN(), NaN()},
+ {0, NaN()},
+ {NaN(), 0},
+ {NaN(), NaN()},
}
var nextafterSC = []float64{
NaN(),
@@ -1200,70 +1205,70 @@ var nextafterSC = []float64{
}
var vfpowSC = [][2]float64{
- [2]float64{Inf(-1), -Pi},
- [2]float64{Inf(-1), -3},
- [2]float64{Inf(-1), Copysign(0, -1)},
- [2]float64{Inf(-1), 0},
- [2]float64{Inf(-1), 1},
- [2]float64{Inf(-1), 3},
- [2]float64{Inf(-1), Pi},
- [2]float64{Inf(-1), NaN()},
-
- [2]float64{-Pi, Inf(-1)},
- [2]float64{-Pi, -Pi},
- [2]float64{-Pi, Copysign(0, -1)},
- [2]float64{-Pi, 0},
- [2]float64{-Pi, 1},
- [2]float64{-Pi, Pi},
- [2]float64{-Pi, Inf(1)},
- [2]float64{-Pi, NaN()},
-
- [2]float64{-1, Inf(-1)},
- [2]float64{-1, Inf(1)},
- [2]float64{-1, NaN()},
- [2]float64{-1 / 2, Inf(-1)},
- [2]float64{-1 / 2, Inf(1)},
- [2]float64{Copysign(0, -1), Inf(-1)},
- [2]float64{Copysign(0, -1), -Pi},
- [2]float64{Copysign(0, -1), -3},
- [2]float64{Copysign(0, -1), 3},
- [2]float64{Copysign(0, -1), Pi},
- [2]float64{Copysign(0, -1), Inf(1)},
-
- [2]float64{0, Inf(-1)},
- [2]float64{0, -Pi},
- [2]float64{0, -3},
- [2]float64{0, Copysign(0, -1)},
- [2]float64{0, 0},
- [2]float64{0, 3},
- [2]float64{0, Pi},
- [2]float64{0, Inf(1)},
- [2]float64{0, NaN()},
-
- [2]float64{1 / 2, Inf(-1)},
- [2]float64{1 / 2, Inf(1)},
- [2]float64{1, Inf(-1)},
- [2]float64{1, Inf(1)},
- [2]float64{1, NaN()},
-
- [2]float64{Pi, Inf(-1)},
- [2]float64{Pi, Copysign(0, -1)},
- [2]float64{Pi, 0},
- [2]float64{Pi, 1},
- [2]float64{Pi, Inf(1)},
- [2]float64{Pi, NaN()},
- [2]float64{Inf(1), -Pi},
- [2]float64{Inf(1), Copysign(0, -1)},
- [2]float64{Inf(1), 0},
- [2]float64{Inf(1), 1},
- [2]float64{Inf(1), Pi},
- [2]float64{Inf(1), NaN()},
- [2]float64{NaN(), -Pi},
- [2]float64{NaN(), Copysign(0, -1)},
- [2]float64{NaN(), 0},
- [2]float64{NaN(), 1},
- [2]float64{NaN(), Pi},
- [2]float64{NaN(), NaN()},
+ {Inf(-1), -Pi},
+ {Inf(-1), -3},
+ {Inf(-1), Copysign(0, -1)},
+ {Inf(-1), 0},
+ {Inf(-1), 1},
+ {Inf(-1), 3},
+ {Inf(-1), Pi},
+ {Inf(-1), NaN()},
+
+ {-Pi, Inf(-1)},
+ {-Pi, -Pi},
+ {-Pi, Copysign(0, -1)},
+ {-Pi, 0},
+ {-Pi, 1},
+ {-Pi, Pi},
+ {-Pi, Inf(1)},
+ {-Pi, NaN()},
+
+ {-1, Inf(-1)},
+ {-1, Inf(1)},
+ {-1, NaN()},
+ {-1 / 2, Inf(-1)},
+ {-1 / 2, Inf(1)},
+ {Copysign(0, -1), Inf(-1)},
+ {Copysign(0, -1), -Pi},
+ {Copysign(0, -1), -3},
+ {Copysign(0, -1), 3},
+ {Copysign(0, -1), Pi},
+ {Copysign(0, -1), Inf(1)},
+
+ {0, Inf(-1)},
+ {0, -Pi},
+ {0, -3},
+ {0, Copysign(0, -1)},
+ {0, 0},
+ {0, 3},
+ {0, Pi},
+ {0, Inf(1)},
+ {0, NaN()},
+
+ {1 / 2, Inf(-1)},
+ {1 / 2, Inf(1)},
+ {1, Inf(-1)},
+ {1, Inf(1)},
+ {1, NaN()},
+
+ {Pi, Inf(-1)},
+ {Pi, Copysign(0, -1)},
+ {Pi, 0},
+ {Pi, 1},
+ {Pi, Inf(1)},
+ {Pi, NaN()},
+ {Inf(1), -Pi},
+ {Inf(1), Copysign(0, -1)},
+ {Inf(1), 0},
+ {Inf(1), 1},
+ {Inf(1), Pi},
+ {Inf(1), NaN()},
+ {NaN(), -Pi},
+ {NaN(), Copysign(0, -1)},
+ {NaN(), 0},
+ {NaN(), 1},
+ {NaN(), Pi},
+ {NaN(), NaN()},
}
var powSC = []float64{
0, // pow(-Inf, -Pi)
@@ -1467,12 +1472,12 @@ func TestAcos(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := vf[i] / 10
if f := Acos(a); !close(acos[i], f) {
- t.Errorf("Acos(%g) = %g, want %g\n", a, f, acos[i])
+ t.Errorf("Acos(%g) = %g, want %g", a, f, acos[i])
}
}
for i := 0; i < len(vfacosSC); i++ {
if f := Acos(vfacosSC[i]); !alike(acosSC[i], f) {
- t.Errorf("Acos(%g) = %g, want %g\n", vfacosSC[i], f, acosSC[i])
+ t.Errorf("Acos(%g) = %g, want %g", vfacosSC[i], f, acosSC[i])
}
}
}
@@ -1481,12 +1486,12 @@ func TestAcosh(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := 1 + Fabs(vf[i])
if f := Acosh(a); !veryclose(acosh[i], f) {
- t.Errorf("Acosh(%g) = %g, want %g\n", a, f, acosh[i])
+ t.Errorf("Acosh(%g) = %g, want %g", a, f, acosh[i])
}
}
for i := 0; i < len(vfacoshSC); i++ {
if f := Acosh(vfacoshSC[i]); !alike(acoshSC[i], f) {
- t.Errorf("Acosh(%g) = %g, want %g\n", vfacoshSC[i], f, acoshSC[i])
+ t.Errorf("Acosh(%g) = %g, want %g", vfacoshSC[i], f, acoshSC[i])
}
}
}
@@ -1495,12 +1500,12 @@ func TestAsin(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := vf[i] / 10
if f := Asin(a); !veryclose(asin[i], f) {
- t.Errorf("Asin(%g) = %g, want %g\n", a, f, asin[i])
+ t.Errorf("Asin(%g) = %g, want %g", a, f, asin[i])
}
}
for i := 0; i < len(vfasinSC); i++ {
if f := Asin(vfasinSC[i]); !alike(asinSC[i], f) {
- t.Errorf("Asin(%g) = %g, want %g\n", vfasinSC[i], f, asinSC[i])
+ t.Errorf("Asin(%g) = %g, want %g", vfasinSC[i], f, asinSC[i])
}
}
}
@@ -1508,12 +1513,12 @@ func TestAsin(t *testing.T) {
func TestAsinh(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Asinh(vf[i]); !veryclose(asinh[i], f) {
- t.Errorf("Asinh(%g) = %g, want %g\n", vf[i], f, asinh[i])
+ t.Errorf("Asinh(%g) = %g, want %g", vf[i], f, asinh[i])
}
}
for i := 0; i < len(vfasinhSC); i++ {
if f := Asinh(vfasinhSC[i]); !alike(asinhSC[i], f) {
- t.Errorf("Asinh(%g) = %g, want %g\n", vfasinhSC[i], f, asinhSC[i])
+ t.Errorf("Asinh(%g) = %g, want %g", vfasinhSC[i], f, asinhSC[i])
}
}
}
@@ -1521,12 +1526,12 @@ func TestAsinh(t *testing.T) {
func TestAtan(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Atan(vf[i]); !veryclose(atan[i], f) {
- t.Errorf("Atan(%g) = %g, want %g\n", vf[i], f, atan[i])
+ t.Errorf("Atan(%g) = %g, want %g", vf[i], f, atan[i])
}
}
for i := 0; i < len(vfatanSC); i++ {
if f := Atan(vfatanSC[i]); !alike(atanSC[i], f) {
- t.Errorf("Atan(%g) = %g, want %g\n", vfatanSC[i], f, atanSC[i])
+ t.Errorf("Atan(%g) = %g, want %g", vfatanSC[i], f, atanSC[i])
}
}
}
@@ -1535,12 +1540,12 @@ func TestAtanh(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := vf[i] / 10
if f := Atanh(a); !veryclose(atanh[i], f) {
- t.Errorf("Atanh(%g) = %g, want %g\n", a, f, atanh[i])
+ t.Errorf("Atanh(%g) = %g, want %g", a, f, atanh[i])
}
}
for i := 0; i < len(vfatanhSC); i++ {
if f := Atanh(vfatanhSC[i]); !alike(atanhSC[i], f) {
- t.Errorf("Atanh(%g) = %g, want %g\n", vfatanhSC[i], f, atanhSC[i])
+ t.Errorf("Atanh(%g) = %g, want %g", vfatanhSC[i], f, atanhSC[i])
}
}
}
@@ -1548,12 +1553,12 @@ func TestAtanh(t *testing.T) {
func TestAtan2(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Atan2(10, vf[i]); !veryclose(atan2[i], f) {
- t.Errorf("Atan2(10, %g) = %g, want %g\n", vf[i], f, atan2[i])
+ t.Errorf("Atan2(10, %g) = %g, want %g", vf[i], f, atan2[i])
}
}
for i := 0; i < len(vfatan2SC); i++ {
if f := Atan2(vfatan2SC[i][0], vfatan2SC[i][1]); !alike(atan2SC[i], f) {
- t.Errorf("Atan2(%g, %g) = %g, want %g\n", vfatan2SC[i][0], vfatan2SC[i][1], f, atan2SC[i])
+ t.Errorf("Atan2(%g, %g) = %g, want %g", vfatan2SC[i][0], vfatan2SC[i][1], f, atan2SC[i])
}
}
}
@@ -1561,12 +1566,12 @@ func TestAtan2(t *testing.T) {
func TestCbrt(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Cbrt(vf[i]); !veryclose(cbrt[i], f) {
- t.Errorf("Cbrt(%g) = %g, want %g\n", vf[i], f, cbrt[i])
+ t.Errorf("Cbrt(%g) = %g, want %g", vf[i], f, cbrt[i])
}
}
for i := 0; i < len(vfcbrtSC); i++ {
if f := Cbrt(vfcbrtSC[i]); !alike(cbrtSC[i], f) {
- t.Errorf("Cbrt(%g) = %g, want %g\n", vfcbrtSC[i], f, cbrtSC[i])
+ t.Errorf("Cbrt(%g) = %g, want %g", vfcbrtSC[i], f, cbrtSC[i])
}
}
}
@@ -1574,12 +1579,12 @@ func TestCbrt(t *testing.T) {
func TestCeil(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Ceil(vf[i]); ceil[i] != f {
- t.Errorf("Ceil(%g) = %g, want %g\n", vf[i], f, ceil[i])
+ t.Errorf("Ceil(%g) = %g, want %g", vf[i], f, ceil[i])
}
}
for i := 0; i < len(vfceilSC); i++ {
if f := Ceil(vfceilSC[i]); !alike(ceilSC[i], f) {
- t.Errorf("Ceil(%g) = %g, want %g\n", vfceilSC[i], f, ceilSC[i])
+ t.Errorf("Ceil(%g) = %g, want %g", vfceilSC[i], f, ceilSC[i])
}
}
}
@@ -1587,12 +1592,17 @@ func TestCeil(t *testing.T) {
func TestCopysign(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Copysign(vf[i], -1); copysign[i] != f {
- t.Errorf("Copysign(%g, -1) = %g, want %g\n", vf[i], f, copysign[i])
+ t.Errorf("Copysign(%g, -1) = %g, want %g", vf[i], f, copysign[i])
+ }
+ }
+ for i := 0; i < len(vf); i++ {
+ if f := Copysign(vf[i], 1); -copysign[i] != f {
+ t.Errorf("Copysign(%g, 1) = %g, want %g", vf[i], f, -copysign[i])
}
}
for i := 0; i < len(vfcopysignSC); i++ {
if f := Copysign(vfcopysignSC[i], -1); !alike(copysignSC[i], f) {
- t.Errorf("Copysign(%g, -1) = %g, want %g\n", vfcopysignSC[i], f, copysignSC[i])
+ t.Errorf("Copysign(%g, -1) = %g, want %g", vfcopysignSC[i], f, copysignSC[i])
}
}
}
@@ -1600,12 +1610,12 @@ func TestCopysign(t *testing.T) {
func TestCos(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Cos(vf[i]); !close(cos[i], f) {
- t.Errorf("Cos(%g) = %g, want %g\n", vf[i], f, cos[i])
+ t.Errorf("Cos(%g) = %g, want %g", vf[i], f, cos[i])
}
}
for i := 0; i < len(vfcosSC); i++ {
if f := Cos(vfcosSC[i]); !alike(cosSC[i], f) {
- t.Errorf("Cos(%g) = %g, want %g\n", vfcosSC[i], f, cosSC[i])
+ t.Errorf("Cos(%g) = %g, want %g", vfcosSC[i], f, cosSC[i])
}
}
}
@@ -1613,12 +1623,12 @@ func TestCos(t *testing.T) {
func TestCosh(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Cosh(vf[i]); !close(cosh[i], f) {
- t.Errorf("Cosh(%g) = %g, want %g\n", vf[i], f, cosh[i])
+ t.Errorf("Cosh(%g) = %g, want %g", vf[i], f, cosh[i])
}
}
for i := 0; i < len(vfcoshSC); i++ {
if f := Cosh(vfcoshSC[i]); !alike(coshSC[i], f) {
- t.Errorf("Cosh(%g) = %g, want %g\n", vfcoshSC[i], f, coshSC[i])
+ t.Errorf("Cosh(%g) = %g, want %g", vfcoshSC[i], f, coshSC[i])
}
}
}
@@ -1627,12 +1637,12 @@ func TestErf(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := vf[i] / 10
if f := Erf(a); !veryclose(erf[i], f) {
- t.Errorf("Erf(%g) = %g, want %g\n", a, f, erf[i])
+ t.Errorf("Erf(%g) = %g, want %g", a, f, erf[i])
}
}
for i := 0; i < len(vferfSC); i++ {
if f := Erf(vferfSC[i]); !alike(erfSC[i], f) {
- t.Errorf("Erf(%g) = %g, want %g\n", vferfSC[i], f, erfSC[i])
+ t.Errorf("Erf(%g) = %g, want %g", vferfSC[i], f, erfSC[i])
}
}
}
@@ -1641,25 +1651,30 @@ func TestErfc(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := vf[i] / 10
if f := Erfc(a); !veryclose(erfc[i], f) {
- t.Errorf("Erfc(%g) = %g, want %g\n", a, f, erfc[i])
+ t.Errorf("Erfc(%g) = %g, want %g", a, f, erfc[i])
}
}
for i := 0; i < len(vferfcSC); i++ {
if f := Erfc(vferfcSC[i]); !alike(erfcSC[i], f) {
- t.Errorf("Erfc(%g) = %g, want %g\n", vferfcSC[i], f, erfcSC[i])
+ t.Errorf("Erfc(%g) = %g, want %g", vferfcSC[i], f, erfcSC[i])
}
}
}
func TestExp(t *testing.T) {
+ testExp(t, Exp, "Exp")
+ testExp(t, ExpGo, "ExpGo")
+}
+
+func testExp(t *testing.T, Exp func(float64) float64, name string) {
for i := 0; i < len(vf); i++ {
if f := Exp(vf[i]); !close(exp[i], f) {
- t.Errorf("Exp(%g) = %g, want %g\n", vf[i], f, exp[i])
+ t.Errorf("%s(%g) = %g, want %g", name, vf[i], f, exp[i])
}
}
for i := 0; i < len(vfexpSC); i++ {
if f := Exp(vfexpSC[i]); !alike(expSC[i], f) {
- t.Errorf("Exp(%g) = %g, want %g\n", vfexpSC[i], f, expSC[i])
+ t.Errorf("%s(%g) = %g, want %g", name, vfexpSC[i], f, expSC[i])
}
}
}
@@ -1668,25 +1683,37 @@ func TestExpm1(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := vf[i] / 100
if f := Expm1(a); !veryclose(expm1[i], f) {
- t.Errorf("Expm1(%g) = %g, want %g\n", a, f, expm1[i])
+ t.Errorf("Expm1(%g) = %g, want %g", a, f, expm1[i])
}
}
for i := 0; i < len(vfexpm1SC); i++ {
if f := Expm1(vfexpm1SC[i]); !alike(expm1SC[i], f) {
- t.Errorf("Expm1(%g) = %g, want %g\n", vfexpm1SC[i], f, expm1SC[i])
+ t.Errorf("Expm1(%g) = %g, want %g", vfexpm1SC[i], f, expm1SC[i])
}
}
}
func TestExp2(t *testing.T) {
+ testExp2(t, Exp2, "Exp2")
+ testExp2(t, Exp2Go, "Exp2Go")
+}
+
+func testExp2(t *testing.T, Exp2 func(float64) float64, name string) {
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])
+ t.Errorf("%s(%g) = %g, want %g", name, 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])
+ t.Errorf("%s(%g) = %g, want %g", name, vfexpSC[i], f, expSC[i])
+ }
+ }
+ for n := -1074; n < 1024; n++ {
+ f := Exp2(float64(n))
+ vf := Ldexp(1, n)
+ if f != vf {
+ t.Errorf("%s(%d) = %g, want %g", name, n, f, vf)
}
}
}
@@ -1694,12 +1721,12 @@ func TestExp2(t *testing.T) {
func TestFabs(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Fabs(vf[i]); fabs[i] != f {
- t.Errorf("Fabs(%g) = %g, want %g\n", vf[i], f, fabs[i])
+ t.Errorf("Fabs(%g) = %g, want %g", vf[i], f, fabs[i])
}
}
for i := 0; i < len(vffabsSC); i++ {
if f := Fabs(vffabsSC[i]); !alike(fabsSC[i], f) {
- t.Errorf("Fabs(%g) = %g, want %g\n", vffabsSC[i], f, fabsSC[i])
+ t.Errorf("Fabs(%g) = %g, want %g", vffabsSC[i], f, fabsSC[i])
}
}
}
@@ -1707,7 +1734,7 @@ func TestFabs(t *testing.T) {
func TestFdim(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Fdim(vf[i], 0); fdim[i] != f {
- t.Errorf("Fdim(%g, %g) = %g, want %g\n", vf[i], 0.0, f, fdim[i])
+ t.Errorf("Fdim(%g, %g) = %g, want %g", vf[i], 0.0, f, fdim[i])
}
}
}
@@ -1715,12 +1742,12 @@ func TestFdim(t *testing.T) {
func TestFloor(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Floor(vf[i]); floor[i] != f {
- t.Errorf("Floor(%g) = %g, want %g\n", vf[i], f, floor[i])
+ t.Errorf("Floor(%g) = %g, want %g", vf[i], f, floor[i])
}
}
for i := 0; i < len(vfceilSC); i++ {
if f := Floor(vfceilSC[i]); !alike(ceilSC[i], f) {
- t.Errorf("Floor(%g) = %g, want %g\n", vfceilSC[i], f, ceilSC[i])
+ t.Errorf("Floor(%g) = %g, want %g", vfceilSC[i], f, ceilSC[i])
}
}
}
@@ -1728,7 +1755,7 @@ func TestFloor(t *testing.T) {
func TestFmax(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Fmax(vf[i], ceil[i]); ceil[i] != f {
- t.Errorf("Fmax(%g, %g) = %g, want %g\n", vf[i], ceil[i], f, ceil[i])
+ t.Errorf("Fmax(%g, %g) = %g, want %g", vf[i], ceil[i], f, ceil[i])
}
}
}
@@ -1736,7 +1763,7 @@ func TestFmax(t *testing.T) {
func TestFmin(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Fmin(vf[i], floor[i]); floor[i] != f {
- t.Errorf("Fmin(%g, %g) = %g, want %g\n", vf[i], floor[i], f, floor[i])
+ t.Errorf("Fmin(%g, %g) = %g, want %g", vf[i], floor[i], f, floor[i])
}
}
}
@@ -1744,12 +1771,12 @@ func TestFmin(t *testing.T) {
func TestFmod(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Fmod(10, vf[i]); fmod[i] != f {
- t.Errorf("Fmod(10, %g) = %g, want %g\n", vf[i], f, fmod[i])
+ t.Errorf("Fmod(10, %g) = %g, want %g", vf[i], f, fmod[i])
}
}
for i := 0; i < len(vffmodSC); i++ {
if f := Fmod(vffmodSC[i][0], vffmodSC[i][1]); !alike(fmodSC[i], f) {
- t.Errorf("Fmod(%g, %g) = %g, want %g\n", vffmodSC[i][0], vffmodSC[i][1], f, fmodSC[i])
+ t.Errorf("Fmod(%g, %g) = %g, want %g", vffmodSC[i][0], vffmodSC[i][1], f, fmodSC[i])
}
}
}
@@ -1757,12 +1784,12 @@ func TestFmod(t *testing.T) {
func TestFrexp(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f, j := Frexp(vf[i]); !veryclose(frexp[i].f, f) || frexp[i].i != j {
- t.Errorf("Frexp(%g) = %g, %d, want %g, %d\n", vf[i], f, j, frexp[i].f, frexp[i].i)
+ t.Errorf("Frexp(%g) = %g, %d, want %g, %d", vf[i], f, j, frexp[i].f, frexp[i].i)
}
}
for i := 0; i < len(vffrexpSC); i++ {
if f, j := Frexp(vffrexpSC[i]); !alike(frexpSC[i].f, f) || frexpSC[i].i != j {
- t.Errorf("Frexp(%g) = %g, %d, want %g, %d\n", vffrexpSC[i], f, j, frexpSC[i].f, frexpSC[i].i)
+ t.Errorf("Frexp(%g) = %g, %d, want %g, %d", vffrexpSC[i], f, j, frexpSC[i].f, frexpSC[i].i)
}
}
}
@@ -1770,12 +1797,12 @@ func TestFrexp(t *testing.T) {
func TestGamma(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Gamma(vf[i]); !close(gamma[i], f) {
- t.Errorf("Gamma(%g) = %g, want %g\n", vf[i], f, gamma[i])
+ t.Errorf("Gamma(%g) = %g, want %g", vf[i], f, gamma[i])
}
}
for i := 0; i < len(vfgammaSC); i++ {
if f := Gamma(vfgammaSC[i]); !alike(gammaSC[i], f) {
- t.Errorf("Gamma(%g) = %g, want %g\n", vfgammaSC[i], f, gammaSC[i])
+ t.Errorf("Gamma(%g) = %g, want %g", vfgammaSC[i], f, gammaSC[i])
}
}
}
@@ -1784,25 +1811,26 @@ func TestHypot(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := Fabs(1e200 * tanh[i] * Sqrt(2))
if f := Hypot(1e200*tanh[i], 1e200*tanh[i]); !veryclose(a, f) {
- t.Errorf("Hypot(%g, %g) = %g, want %g\n", 1e200*tanh[i], 1e200*tanh[i], f, a)
+ t.Errorf("Hypot(%g, %g) = %g, want %g", 1e200*tanh[i], 1e200*tanh[i], f, a)
}
}
for i := 0; i < len(vfhypotSC); i++ {
if f := Hypot(vfhypotSC[i][0], vfhypotSC[i][1]); !alike(hypotSC[i], f) {
- t.Errorf("Hypot(%g, %g) = %g, want %g\n", vfhypotSC[i][0], vfhypotSC[i][1], f, hypotSC[i])
+ t.Errorf("Hypot(%g, %g) = %g, want %g", vfhypotSC[i][0], vfhypotSC[i][1], f, hypotSC[i])
}
}
}
func TestIlogb(t *testing.T) {
for i := 0; i < len(vf); i++ {
- if e := Ilogb(vf[i]); frexp[i].i != e {
- t.Errorf("Ilogb(%g) = %d, want %d\n", vf[i], e, frexp[i].i)
+ a := frexp[i].i - 1 // adjust because fr in the interval [½, 1)
+ if e := Ilogb(vf[i]); a != e {
+ t.Errorf("Ilogb(%g) = %d, want %d", vf[i], e, a)
}
}
for i := 0; i < len(vflogbSC); i++ {
if e := Ilogb(vflogbSC[i]); ilogbSC[i] != e {
- t.Errorf("Ilogb(%g) = %d, want %d\n", vflogbSC[i], e, ilogbSC[i])
+ t.Errorf("Ilogb(%g) = %d, want %d", vflogbSC[i], e, ilogbSC[i])
}
}
}
@@ -1810,12 +1838,12 @@ func TestIlogb(t *testing.T) {
func TestJ0(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := J0(vf[i]); !soclose(j0[i], f, 4e-14) {
- t.Errorf("J0(%g) = %g, want %g\n", vf[i], f, j0[i])
+ t.Errorf("J0(%g) = %g, want %g", vf[i], f, j0[i])
}
}
for i := 0; i < len(vfj0SC); i++ {
if f := J0(vfj0SC[i]); !alike(j0SC[i], f) {
- t.Errorf("J0(%g) = %g, want %g\n", vfj0SC[i], f, j0SC[i])
+ t.Errorf("J0(%g) = %g, want %g", vfj0SC[i], f, j0SC[i])
}
}
}
@@ -1823,12 +1851,12 @@ func TestJ0(t *testing.T) {
func TestJ1(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := J1(vf[i]); !close(j1[i], f) {
- t.Errorf("J1(%g) = %g, want %g\n", vf[i], f, j1[i])
+ t.Errorf("J1(%g) = %g, want %g", vf[i], f, j1[i])
}
}
for i := 0; i < len(vfj0SC); i++ {
if f := J1(vfj0SC[i]); !alike(j1SC[i], f) {
- t.Errorf("J1(%g) = %g, want %g\n", vfj0SC[i], f, j1SC[i])
+ t.Errorf("J1(%g) = %g, want %g", vfj0SC[i], f, j1SC[i])
}
}
}
@@ -1836,18 +1864,18 @@ func TestJ1(t *testing.T) {
func TestJn(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Jn(2, vf[i]); !close(j2[i], f) {
- t.Errorf("Jn(2, %g) = %g, want %g\n", vf[i], f, j2[i])
+ t.Errorf("Jn(2, %g) = %g, want %g", vf[i], f, j2[i])
}
if f := Jn(-3, vf[i]); !close(jM3[i], f) {
- t.Errorf("Jn(-3, %g) = %g, want %g\n", vf[i], f, jM3[i])
+ t.Errorf("Jn(-3, %g) = %g, want %g", vf[i], f, jM3[i])
}
}
for i := 0; i < len(vfj0SC); i++ {
if f := Jn(2, vfj0SC[i]); !alike(j2SC[i], f) {
- t.Errorf("Jn(2, %g) = %g, want %g\n", vfj0SC[i], f, j2SC[i])
+ t.Errorf("Jn(2, %g) = %g, want %g", vfj0SC[i], f, j2SC[i])
}
if f := Jn(-3, vfj0SC[i]); !alike(jM3SC[i], f) {
- t.Errorf("Jn(-3, %g) = %g, want %g\n", vfj0SC[i], f, jM3SC[i])
+ t.Errorf("Jn(-3, %g) = %g, want %g", vfj0SC[i], f, jM3SC[i])
}
}
}
@@ -1855,12 +1883,12 @@ func TestJn(t *testing.T) {
func TestLdexp(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Ldexp(frexp[i].f, frexp[i].i); !veryclose(vf[i], f) {
- t.Errorf("Ldexp(%g, %d) = %g, want %g\n", frexp[i].f, frexp[i].i, f, vf[i])
+ t.Errorf("Ldexp(%g, %d) = %g, want %g", frexp[i].f, frexp[i].i, f, vf[i])
}
}
for i := 0; i < len(vffrexpSC); i++ {
if f := Ldexp(frexpSC[i].f, frexpSC[i].i); !alike(vffrexpSC[i], f) {
- t.Errorf("Ldexp(%g, %d) = %g, want %g\n", frexpSC[i].f, frexpSC[i].i, f, vffrexpSC[i])
+ t.Errorf("Ldexp(%g, %d) = %g, want %g", frexpSC[i].f, frexpSC[i].i, f, vffrexpSC[i])
}
}
}
@@ -1868,12 +1896,12 @@ func TestLdexp(t *testing.T) {
func TestLgamma(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f, s := Lgamma(vf[i]); !close(lgamma[i].f, f) || lgamma[i].i != s {
- t.Errorf("Lgamma(%g) = %g, %d, want %g, %d\n", vf[i], f, s, lgamma[i].f, lgamma[i].i)
+ t.Errorf("Lgamma(%g) = %g, %d, want %g, %d", vf[i], f, s, lgamma[i].f, lgamma[i].i)
}
}
for i := 0; i < len(vflgammaSC); i++ {
if f, s := Lgamma(vflgammaSC[i]); !alike(lgammaSC[i].f, f) || lgammaSC[i].i != s {
- t.Errorf("Lgamma(%g) = %g, %d, want %g, %d\n", vflgammaSC[i], f, s, lgammaSC[i].f, lgammaSC[i].i)
+ t.Errorf("Lgamma(%g) = %g, %d, want %g, %d", vflgammaSC[i], f, s, lgammaSC[i].f, lgammaSC[i].i)
}
}
}
@@ -1882,15 +1910,15 @@ func TestLog(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := Fabs(vf[i])
if f := Log(a); log[i] != f {
- t.Errorf("Log(%g) = %g, want %g\n", a, f, log[i])
+ t.Errorf("Log(%g) = %g, want %g", a, f, log[i])
}
}
if f := Log(10); f != Ln10 {
- t.Errorf("Log(%g) = %g, want %g\n", 10.0, f, Ln10)
+ t.Errorf("Log(%g) = %g, want %g", 10.0, f, Ln10)
}
for i := 0; i < len(vflogSC); i++ {
if f := Log(vflogSC[i]); !alike(logSC[i], f) {
- t.Errorf("Log(%g) = %g, want %g\n", vflogSC[i], f, logSC[i])
+ t.Errorf("Log(%g) = %g, want %g", vflogSC[i], f, logSC[i])
}
}
}
@@ -1898,12 +1926,12 @@ func TestLog(t *testing.T) {
func TestLogb(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Logb(vf[i]); logb[i] != f {
- t.Errorf("Logb(%g) = %g, want %g\n", vf[i], f, logb[i])
+ t.Errorf("Logb(%g) = %g, want %g", vf[i], f, logb[i])
}
}
for i := 0; i < len(vflogbSC); i++ {
if f := Logb(vflogbSC[i]); !alike(logbSC[i], f) {
- t.Errorf("Logb(%g) = %g, want %g\n", vflogbSC[i], f, logbSC[i])
+ t.Errorf("Logb(%g) = %g, want %g", vflogbSC[i], f, logbSC[i])
}
}
}
@@ -1912,15 +1940,15 @@ func TestLog10(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := Fabs(vf[i])
if f := Log10(a); !veryclose(log10[i], f) {
- t.Errorf("Log10(%g) = %g, want %g\n", a, f, log10[i])
+ t.Errorf("Log10(%g) = %g, want %g", a, f, log10[i])
}
}
if f := Log10(E); f != Log10E {
- t.Errorf("Log10(%g) = %g, want %g\n", E, f, Log10E)
+ t.Errorf("Log10(%g) = %g, want %g", E, f, Log10E)
}
for i := 0; i < len(vflogSC); i++ {
if f := Log10(vflogSC[i]); !alike(logSC[i], f) {
- t.Errorf("Log10(%g) = %g, want %g\n", vflogSC[i], f, logSC[i])
+ t.Errorf("Log10(%g) = %g, want %g", vflogSC[i], f, logSC[i])
}
}
}
@@ -1929,16 +1957,16 @@ func TestLog1p(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := vf[i] / 100
if f := Log1p(a); !veryclose(log1p[i], f) {
- t.Errorf("Log1p(%g) = %g, want %g\n", a, f, log1p[i])
+ t.Errorf("Log1p(%g) = %g, want %g", a, f, log1p[i])
}
}
a := float64(9)
if f := Log1p(a); f != Ln10 {
- t.Errorf("Log1p(%g) = %g, want %g\n", a, f, Ln10)
+ t.Errorf("Log1p(%g) = %g, want %g", a, f, Ln10)
}
for i := 0; i < len(vflogSC); i++ {
if f := Log1p(vflog1pSC[i]); !alike(log1pSC[i], f) {
- t.Errorf("Log1p(%g) = %g, want %g\n", vflog1pSC[i], f, log1pSC[i])
+ t.Errorf("Log1p(%g) = %g, want %g", vflog1pSC[i], f, log1pSC[i])
}
}
}
@@ -1947,15 +1975,15 @@ func TestLog2(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := Fabs(vf[i])
if f := Log2(a); !veryclose(log2[i], f) {
- t.Errorf("Log2(%g) = %g, want %g\n", a, f, log2[i])
+ t.Errorf("Log2(%g) = %g, want %g", a, f, log2[i])
}
}
if f := Log2(E); f != Log2E {
- t.Errorf("Log2(%g) = %g, want %g\n", E, f, Log2E)
+ t.Errorf("Log2(%g) = %g, want %g", E, f, Log2E)
}
for i := 0; i < len(vflogSC); i++ {
if f := Log2(vflogSC[i]); !alike(logSC[i], f) {
- t.Errorf("Log2(%g) = %g, want %g\n", vflogSC[i], f, logSC[i])
+ t.Errorf("Log2(%g) = %g, want %g", vflogSC[i], f, logSC[i])
}
}
}
@@ -1963,12 +1991,12 @@ func TestLog2(t *testing.T) {
func TestModf(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f, g := Modf(vf[i]); !veryclose(modf[i][0], f) || !veryclose(modf[i][1], g) {
- t.Errorf("Modf(%g) = %g, %g, want %g, %g\n", vf[i], f, g, modf[i][0], modf[i][1])
+ t.Errorf("Modf(%g) = %g, %g, want %g, %g", vf[i], f, g, modf[i][0], modf[i][1])
}
}
for i := 0; i < len(vfmodfSC); i++ {
if f, g := Modf(vfmodfSC[i]); !alike(modfSC[i][0], f) || !alike(modfSC[i][1], g) {
- t.Errorf("Modf(%g) = %g, %g, want %g, %g\n", vfmodfSC[i], f, g, modfSC[i][0], modfSC[i][1])
+ t.Errorf("Modf(%g) = %g, %g, want %g, %g", vfmodfSC[i], f, g, modfSC[i][0], modfSC[i][1])
}
}
}
@@ -1976,12 +2004,12 @@ func TestModf(t *testing.T) {
func TestNextafter(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Nextafter(vf[i], 10); nextafter[i] != f {
- t.Errorf("Nextafter(%g, %g) = %g want %g\n", vf[i], 10.0, f, nextafter[i])
+ t.Errorf("Nextafter(%g, %g) = %g want %g", vf[i], 10.0, f, nextafter[i])
}
}
for i := 0; i < len(vfmodfSC); i++ {
if f := Nextafter(vfnextafterSC[i][0], vfnextafterSC[i][1]); !alike(nextafterSC[i], f) {
- t.Errorf("Nextafter(%g, %g) = %g want %g\n", vfnextafterSC[i][0], vfnextafterSC[i][1], f, nextafterSC[i])
+ t.Errorf("Nextafter(%g, %g) = %g want %g", vfnextafterSC[i][0], vfnextafterSC[i][1], f, nextafterSC[i])
}
}
}
@@ -1989,12 +2017,12 @@ func TestNextafter(t *testing.T) {
func TestPow(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Pow(10, vf[i]); !close(pow[i], f) {
- t.Errorf("Pow(10, %g) = %g, want %g\n", vf[i], f, pow[i])
+ t.Errorf("Pow(10, %g) = %g, want %g", vf[i], f, pow[i])
}
}
for i := 0; i < len(vfpowSC); i++ {
if f := Pow(vfpowSC[i][0], vfpowSC[i][1]); !alike(powSC[i], f) {
- t.Errorf("Pow(%g, %g) = %g, want %g\n", vfpowSC[i][0], vfpowSC[i][1], f, powSC[i])
+ t.Errorf("Pow(%g, %g) = %g, want %g", vfpowSC[i][0], vfpowSC[i][1], f, powSC[i])
}
}
}
@@ -2002,12 +2030,12 @@ func TestPow(t *testing.T) {
func TestRemainder(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Remainder(10, vf[i]); remainder[i] != f {
- t.Errorf("Remainder(10, %g) = %g, want %g\n", vf[i], f, remainder[i])
+ t.Errorf("Remainder(10, %g) = %g, want %g", vf[i], f, remainder[i])
}
}
for i := 0; i < len(vffmodSC); i++ {
if f := Remainder(vffmodSC[i][0], vffmodSC[i][1]); !alike(fmodSC[i], f) {
- t.Errorf("Remainder(%g, %g) = %g, want %g\n", vffmodSC[i][0], vffmodSC[i][1], f, fmodSC[i])
+ t.Errorf("Remainder(%g, %g) = %g, want %g", vffmodSC[i][0], vffmodSC[i][1], f, fmodSC[i])
}
}
}
@@ -2015,24 +2043,24 @@ func TestRemainder(t *testing.T) {
func TestSignbit(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Signbit(vf[i]); signbit[i] != f {
- t.Errorf("Signbit(%g) = %t, want %t\n", vf[i], f, signbit[i])
+ t.Errorf("Signbit(%g) = %t, want %t", vf[i], f, signbit[i])
}
}
for i := 0; i < len(vfsignbitSC); i++ {
if f := Signbit(vfsignbitSC[i]); signbitSC[i] != f {
- t.Errorf("Signbit(%g) = %t, want %t\n", vfsignbitSC[i], f, signbitSC[i])
+ t.Errorf("Signbit(%g) = %t, want %t", vfsignbitSC[i], f, signbitSC[i])
}
}
}
func TestSin(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Sin(vf[i]); !close(sin[i], f) {
- t.Errorf("Sin(%g) = %g, want %g\n", vf[i], f, sin[i])
+ t.Errorf("Sin(%g) = %g, want %g", vf[i], f, sin[i])
}
}
for i := 0; i < len(vfsinSC); i++ {
if f := Sin(vfsinSC[i]); !alike(sinSC[i], f) {
- t.Errorf("Sin(%g) = %g, want %g\n", vfsinSC[i], f, sinSC[i])
+ t.Errorf("Sin(%g) = %g, want %g", vfsinSC[i], f, sinSC[i])
}
}
}
@@ -2040,7 +2068,7 @@ func TestSin(t *testing.T) {
func TestSincos(t *testing.T) {
for i := 0; i < len(vf); i++ {
if s, c := Sincos(vf[i]); !close(sin[i], s) || !close(cos[i], c) {
- t.Errorf("Sincos(%g) = %g, %g want %g, %g\n", vf[i], s, c, sin[i], cos[i])
+ t.Errorf("Sincos(%g) = %g, %g want %g, %g", vf[i], s, c, sin[i], cos[i])
}
}
}
@@ -2048,12 +2076,12 @@ func TestSincos(t *testing.T) {
func TestSinh(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Sinh(vf[i]); !close(sinh[i], f) {
- t.Errorf("Sinh(%g) = %g, want %g\n", vf[i], f, sinh[i])
+ t.Errorf("Sinh(%g) = %g, want %g", vf[i], f, sinh[i])
}
}
for i := 0; i < len(vfsinhSC); i++ {
if f := Sinh(vfsinhSC[i]); !alike(sinhSC[i], f) {
- t.Errorf("Sinh(%g) = %g, want %g\n", vfsinhSC[i], f, sinhSC[i])
+ t.Errorf("Sinh(%g) = %g, want %g", vfsinhSC[i], f, sinhSC[i])
}
}
}
@@ -2062,19 +2090,19 @@ func TestSqrt(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := Fabs(vf[i])
if f := SqrtGo(a); sqrt[i] != f {
- t.Errorf("SqrtGo(%g) = %g, want %g\n", a, f, sqrt[i])
+ t.Errorf("SqrtGo(%g) = %g, want %g", a, f, sqrt[i])
}
a = Fabs(vf[i])
if f := Sqrt(a); sqrt[i] != f {
- t.Errorf("Sqrt(%g) = %g, want %g\n", a, f, sqrt[i])
+ t.Errorf("Sqrt(%g) = %g, want %g", a, f, sqrt[i])
}
}
for i := 0; i < len(vfsqrtSC); i++ {
if f := SqrtGo(vfsqrtSC[i]); !alike(sqrtSC[i], f) {
- t.Errorf("SqrtGo(%g) = %g, want %g\n", vfsqrtSC[i], f, sqrtSC[i])
+ t.Errorf("SqrtGo(%g) = %g, want %g", vfsqrtSC[i], f, sqrtSC[i])
}
if f := Sqrt(vfsqrtSC[i]); !alike(sqrtSC[i], f) {
- t.Errorf("Sqrt(%g) = %g, want %g\n", vfsqrtSC[i], f, sqrtSC[i])
+ t.Errorf("Sqrt(%g) = %g, want %g", vfsqrtSC[i], f, sqrtSC[i])
}
}
}
@@ -2082,13 +2110,23 @@ func TestSqrt(t *testing.T) {
func TestTan(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Tan(vf[i]); !close(tan[i], f) {
- t.Errorf("Tan(%g) = %g, want %g\n", vf[i], f, tan[i])
+ t.Errorf("Tan(%g) = %g, want %g", vf[i], f, tan[i])
}
}
// same special cases as Sin
for i := 0; i < len(vfsinSC); i++ {
if f := Tan(vfsinSC[i]); !alike(sinSC[i], f) {
- t.Errorf("Tan(%g) = %g, want %g\n", vfsinSC[i], f, sinSC[i])
+ t.Errorf("Tan(%g) = %g, want %g", vfsinSC[i], f, sinSC[i])
+ }
+ }
+
+ // Make sure portable Tan(Pi/2) doesn't panic (it used to).
+ // The portable implementation returns NaN.
+ // Assembly implementations might not,
+ // because Pi/2 is not exactly representable.
+ if runtime.GOARCH != "386" {
+ if f := Tan(Pi / 2); !alike(f, NaN()) {
+ t.Errorf("Tan(%g) = %g, want %g", Pi/2, f, NaN())
}
}
}
@@ -2096,12 +2134,12 @@ func TestTan(t *testing.T) {
func TestTanh(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Tanh(vf[i]); !veryclose(tanh[i], f) {
- t.Errorf("Tanh(%g) = %g, want %g\n", vf[i], f, tanh[i])
+ t.Errorf("Tanh(%g) = %g, want %g", vf[i], f, tanh[i])
}
}
for i := 0; i < len(vftanhSC); i++ {
if f := Tanh(vftanhSC[i]); !alike(tanhSC[i], f) {
- t.Errorf("Tanh(%g) = %g, want %g\n", vftanhSC[i], f, tanhSC[i])
+ t.Errorf("Tanh(%g) = %g, want %g", vftanhSC[i], f, tanhSC[i])
}
}
}
@@ -2109,12 +2147,12 @@ func TestTanh(t *testing.T) {
func TestTrunc(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := Trunc(vf[i]); trunc[i] != f {
- t.Errorf("Trunc(%g) = %g, want %g\n", vf[i], f, trunc[i])
+ t.Errorf("Trunc(%g) = %g, want %g", vf[i], f, trunc[i])
}
}
for i := 0; i < len(vfceilSC); i++ {
if f := Trunc(vfceilSC[i]); !alike(ceilSC[i], f) {
- t.Errorf("Trunc(%g) = %g, want %g\n", vfceilSC[i], f, ceilSC[i])
+ t.Errorf("Trunc(%g) = %g, want %g", vfceilSC[i], f, ceilSC[i])
}
}
}
@@ -2123,12 +2161,12 @@ func TestY0(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := Fabs(vf[i])
if f := Y0(a); !close(y0[i], f) {
- t.Errorf("Y0(%g) = %g, want %g\n", a, f, y0[i])
+ t.Errorf("Y0(%g) = %g, want %g", a, f, y0[i])
}
}
for i := 0; i < len(vfy0SC); i++ {
if f := Y0(vfy0SC[i]); !alike(y0SC[i], f) {
- t.Errorf("Y0(%g) = %g, want %g\n", vfy0SC[i], f, y0SC[i])
+ t.Errorf("Y0(%g) = %g, want %g", vfy0SC[i], f, y0SC[i])
}
}
}
@@ -2137,12 +2175,12 @@ func TestY1(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := Fabs(vf[i])
if f := Y1(a); !soclose(y1[i], f, 2e-14) {
- t.Errorf("Y1(%g) = %g, want %g\n", a, f, y1[i])
+ t.Errorf("Y1(%g) = %g, want %g", a, f, y1[i])
}
}
for i := 0; i < len(vfy0SC); i++ {
if f := Y1(vfy0SC[i]); !alike(y1SC[i], f) {
- t.Errorf("Y1(%g) = %g, want %g\n", vfy0SC[i], f, y1SC[i])
+ t.Errorf("Y1(%g) = %g, want %g", vfy0SC[i], f, y1SC[i])
}
}
}
@@ -2151,18 +2189,18 @@ func TestYn(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := Fabs(vf[i])
if f := Yn(2, a); !close(y2[i], f) {
- t.Errorf("Yn(2, %g) = %g, want %g\n", a, f, y2[i])
+ t.Errorf("Yn(2, %g) = %g, want %g", a, f, y2[i])
}
if f := Yn(-3, a); !close(yM3[i], f) {
- t.Errorf("Yn(-3, %g) = %g, want %g\n", a, f, yM3[i])
+ t.Errorf("Yn(-3, %g) = %g, want %g", a, f, yM3[i])
}
}
for i := 0; i < len(vfy0SC); i++ {
if f := Yn(2, vfy0SC[i]); !alike(y2SC[i], f) {
- t.Errorf("Yn(2, %g) = %g, want %g\n", vfy0SC[i], f, y2SC[i])
+ t.Errorf("Yn(2, %g) = %g, want %g", vfy0SC[i], f, y2SC[i])
}
if f := Yn(-3, vfy0SC[i]); !alike(yM3SC[i], f) {
- t.Errorf("Yn(-3, %g) = %g, want %g\n", vfy0SC[i], f, yM3SC[i])
+ t.Errorf("Yn(-3, %g) = %g, want %g", vfy0SC[i], f, yM3SC[i])
}
}
}
@@ -2175,7 +2213,7 @@ func TestLargeCos(t *testing.T) {
f1 := Cos(vf[i])
f2 := Cos(vf[i] + large)
if !kindaclose(f1, f2) {
- t.Errorf("Cos(%g) = %g, want %g\n", vf[i]+large, f2, f1)
+ t.Errorf("Cos(%g) = %g, want %g", vf[i]+large, f2, f1)
}
}
}
@@ -2186,7 +2224,7 @@ func TestLargeSin(t *testing.T) {
f1 := Sin(vf[i])
f2 := Sin(vf[i] + large)
if !kindaclose(f1, f2) {
- t.Errorf("Sin(%g) = %g, want %g\n", vf[i]+large, f2, f1)
+ t.Errorf("Sin(%g) = %g, want %g", vf[i]+large, f2, f1)
}
}
}
@@ -2197,7 +2235,7 @@ func TestLargeSincos(t *testing.T) {
f1, g1 := Sincos(vf[i])
f2, g2 := Sincos(vf[i] + large)
if !kindaclose(f1, f2) || !kindaclose(g1, g2) {
- t.Errorf("Sincos(%g) = %g, %g, want %g, %g\n", vf[i]+large, f2, g2, f1, g1)
+ t.Errorf("Sincos(%g) = %g, %g, want %g, %g", vf[i]+large, f2, g2, f1, g1)
}
}
}
@@ -2208,7 +2246,7 @@ func TestLargeTan(t *testing.T) {
f1 := Tan(vf[i])
f2 := Tan(vf[i] + large)
if !kindaclose(f1, f2) {
- t.Errorf("Tan(%g) = %g, want %g\n", vf[i]+large, f2, f1)
+ t.Errorf("Tan(%g) = %g, want %g", vf[i]+large, f2, f1)
}
}
}
@@ -2224,10 +2262,10 @@ type floatTest struct {
}
var floatTests = []floatTest{
- floatTest{float64(MaxFloat64), "MaxFloat64", "1.7976931348623157e+308"},
- floatTest{float64(MinFloat64), "MinFloat64", "5e-324"},
- floatTest{float32(MaxFloat32), "MaxFloat32", "3.4028235e+38"},
- floatTest{float32(MinFloat32), "MinFloat32", "1e-45"},
+ {float64(MaxFloat64), "MaxFloat64", "1.7976931348623157e+308"},
+ {float64(SmallestNonzeroFloat64), "SmallestNonzeroFloat64", "5e-324"},
+ {float32(MaxFloat32), "MaxFloat32", "3.4028235e+38"},
+ {float32(SmallestNonzeroFloat32), "SmallestNonzeroFloat32", "1e-45"},
}
func TestFloatMinMax(t *testing.T) {
@@ -2331,6 +2369,12 @@ func BenchmarkExp(b *testing.B) {
}
}
+func BenchmarkExpGo(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ ExpGo(.5)
+ }
+}
+
func BenchmarkExpm1(b *testing.B) {
for i := 0; i < b.N; i++ {
Expm1(.5)
@@ -2343,6 +2387,12 @@ func BenchmarkExp2(b *testing.B) {
}
}
+func BenchmarkExp2Go(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ Exp2Go(.5)
+ }
+}
+
func BenchmarkFabs(b *testing.B) {
for i := 0; i < b.N; i++ {
Fabs(.5)
diff --git a/src/pkg/math/bits.go b/src/pkg/math/bits.go
index d36cd18d7..1a97e7679 100644
--- a/src/pkg/math/bits.go
+++ b/src/pkg/math/bits.go
@@ -10,7 +10,7 @@ const (
uvneginf = 0xFFF0000000000000
mask = 0x7FF
shift = 64 - 11 - 1
- bias = 1022
+ bias = 1023
)
// Inf returns positive infinity if sign >= 0, negative infinity if sign < 0.
diff --git a/src/pkg/math/const.go b/src/pkg/math/const.go
index 6a78d00a0..b53527a4f 100644
--- a/src/pkg/math/const.go
+++ b/src/pkg/math/const.go
@@ -25,13 +25,13 @@ const (
// Floating-point limit values.
// Max is the largest finite value representable by the type.
-// Min is the smallest nonzero value representable by the type.
+// SmallestNonzero is the smallest positive, non-zero value representable by the type.
const (
- MaxFloat32 = 3.40282346638528859811704183484516925440e+38 /* 2**127 * (2**24 - 1) / 2**23 */
- MinFloat32 = 1.401298464324817070923729583289916131280e-45 /* 1 / 2**(127 - 1 + 23) */
+ MaxFloat32 = 3.40282346638528859811704183484516925440e+38 /* 2**127 * (2**24 - 1) / 2**23 */
+ SmallestNonzeroFloat32 = 1.401298464324817070923729583289916131280e-45 /* 1 / 2**(127 - 1 + 23) */
- MaxFloat64 = 1.797693134862315708145274237317043567981e+308 /* 2**1023 * (2**53 - 1) / 2**52 */
- MinFloat64 = 4.940656458412465441765687928682213723651e-324 /* 1 / 2**(1023 - 1 + 52) */
+ MaxFloat64 = 1.797693134862315708145274237317043567981e+308 /* 2**1023 * (2**53 - 1) / 2**52 */
+ SmallestNonzeroFloat64 = 4.940656458412465441765687928682213723651e-324 /* 1 / 2**(1023 - 1 + 52) */
)
// Integer limit values.
diff --git a/src/pkg/math/exp.go b/src/pkg/math/exp.go
index 90409c341..c519c2cb6 100644
--- a/src/pkg/math/exp.go
+++ b/src/pkg/math/exp.go
@@ -4,83 +4,6 @@
package math
-
-// The original C code, the long comment, and the constants
-// below are from FreeBSD's /usr/src/lib/msun/src/e_exp.c
-// and came with this notice. The go code is a simplified
-// version of the original C.
-//
-// ====================================================
-// Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
-//
-// Permission to use, copy, modify, and distribute this
-// software is freely granted, provided that this notice
-// is preserved.
-// ====================================================
-//
-//
-// exp(x)
-// Returns the exponential of x.
-//
-// Method
-// 1. Argument reduction:
-// Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
-// Given x, find r and integer k such that
-//
-// x = k*ln2 + r, |r| <= 0.5*ln2.
-//
-// Here r will be represented as r = hi-lo for better
-// accuracy.
-//
-// 2. Approximation of exp(r) by a special rational function on
-// the interval [0,0.34658]:
-// Write
-// R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
-// We use a special Remes algorithm on [0,0.34658] to generate
-// a polynomial of degree 5 to approximate R. The maximum error
-// of this polynomial approximation is bounded by 2**-59. In
-// other words,
-// R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
-// (where z=r*r, and the values of P1 to P5 are listed below)
-// and
-// | 5 | -59
-// | 2.0+P1*z+...+P5*z - R(z) | <= 2
-// | |
-// The computation of exp(r) thus becomes
-// 2*r
-// exp(r) = 1 + -------
-// R - r
-// r*R1(r)
-// = 1 + r + ----------- (for better accuracy)
-// 2 - R1(r)
-// where
-// 2 4 10
-// R1(r) = r - (P1*r + P2*r + ... + P5*r ).
-//
-// 3. Scale back to obtain exp(x):
-// From step 1, we have
-// exp(x) = 2**k * exp(r)
-//
-// Special cases:
-// exp(INF) is INF, exp(NaN) is NaN;
-// exp(-INF) is 0, and
-// for finite argument, only exp(0)=1 is exact.
-//
-// Accuracy:
-// according to an error analysis, the error is always less than
-// 1 ulp (unit in the last place).
-//
-// Misc. info.
-// For IEEE double
-// if x > 7.09782712893383973096e+02 then exp(x) overflow
-// if x < -7.45133219101941108420e+02 then exp(x) underflow
-//
-// Constants:
-// The hexadecimal values are the intended ones for the following
-// constants. The decimal values may be used, provided that the
-// compiler will convert from decimal to binary accurately enough
-// to produce the hexadecimal values shown.
-
// Exp returns e**x, the base-e exponential of x.
//
// Special cases are:
@@ -88,54 +11,4 @@ package math
// Exp(NaN) = NaN
// Very large values overflow to 0 or +Inf.
// Very small values underflow to 1.
-func Exp(x float64) float64 {
- const (
- Ln2Hi = 6.93147180369123816490e-01
- Ln2Lo = 1.90821492927058770002e-10
- Log2e = 1.44269504088896338700e+00
- P1 = 1.66666666666666019037e-01 /* 0x3FC55555; 0x5555553E */
- P2 = -2.77777777770155933842e-03 /* 0xBF66C16C; 0x16BEBD93 */
- P3 = 6.61375632143793436117e-05 /* 0x3F11566A; 0xAF25DE2C */
- P4 = -1.65339022054652515390e-06 /* 0xBEBBBD41; 0xC5D26BF1 */
- P5 = 4.13813679705723846039e-08 /* 0x3E663769; 0x72BEA4D0 */
-
- Overflow = 7.09782712893383973096e+02
- Underflow = -7.45133219101941108420e+02
- NearZero = 1.0 / (1 << 28) // 2**-28
- )
-
- // TODO(rsc): Remove manual inlining of IsNaN, IsInf
- // when compiler does it for us
- // special cases
- switch {
- case x != x || x > MaxFloat64: // IsNaN(x) || IsInf(x, 1):
- return x
- case x < -MaxFloat64: // IsInf(x, -1):
- return 0
- case x > Overflow:
- return Inf(1)
- case x < Underflow:
- return 0
- case -NearZero < x && x < NearZero:
- return 1
- }
-
- // reduce; computed as r = hi - lo for extra precision.
- var k int
- switch {
- case x < 0:
- k = int(Log2e*x - 0.5)
- case x > 0:
- k = int(Log2e*x + 0.5)
- }
- hi := x - float64(k)*Ln2Hi
- lo := float64(k) * Ln2Lo
- r := hi - lo
-
- // compute
- t := r * r
- c := r - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))))
- y := 1 - ((lo - (r*c)/(2-c)) - hi)
- // TODO(rsc): make sure Ldexp can handle boundary k
- return Ldexp(y, k)
-}
+func Exp(x float64) float64 { return expGo(x) }
diff --git a/src/pkg/math/exp2.go b/src/pkg/math/exp2.go
index 1e67f29eb..1cface9d3 100644
--- a/src/pkg/math/exp2.go
+++ b/src/pkg/math/exp2.go
@@ -7,4 +7,4 @@ package math
// 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) }
+func Exp2(x float64) float64 { return exp2Go(x) }
diff --git a/src/pkg/math/exp_amd64.s b/src/pkg/math/exp_amd64.s
index 844b5c923..74c9c876a 100644
--- a/src/pkg/math/exp_amd64.s
+++ b/src/pkg/math/exp_amd64.s
@@ -19,20 +19,32 @@
#define LOG2E 1.4426950408889634073599246810018920 // 1/LN2
#define LN2U 0.69314718055966295651160180568695068359375 // upper half LN2
#define LN2L 0.28235290563031577122588448175013436025525412068e-12 // lower half LN2
+#define T0 1.0
+#define T1 0.5
+#define T2 1.6666666666666666667e-1
+#define T3 4.1666666666666666667e-2
+#define T4 8.3333333333333333333e-3
+#define T5 1.3888888888888888889e-3
+#define T6 1.9841269841269841270e-4
+#define T7 2.4801587301587301587e-5
+#define PosInf 0x7FF0000000000000
+#define NegInf 0xFFF0000000000000
// func Exp(x float64) float64
TEXT ·Exp(SB),7,$0
// test bits for not-finite
- MOVQ x+0(FP), AX
- MOVQ $0x7ff0000000000000, BX
- ANDQ BX, AX
- CMPQ BX, AX
- JEQ not_finite
- MOVSD x+0(FP), X0
+ MOVQ x+0(FP), BX
+ MOVQ $~(1<<63), AX // sign bit mask
+ MOVQ BX, DX
+ ANDQ AX, DX
+ MOVQ $PosInf, AX
+ CMPQ AX, DX
+ JLE notFinite
+ MOVQ BX, X0
MOVSD $LOG2E, X1
MULSD X0, X1
- CVTTSD2SQ X1, BX // BX = exponent
- CVTSQ2SD BX, X1
+ CVTSD2SL X1, BX // BX = exponent
+ CVTSL2SD BX, X1
MOVSD $LN2U, X2
MULSD X1, X2
SUBSD X2, X0
@@ -40,31 +52,23 @@ TEXT ·Exp(SB),7,$0
MULSD X1, X2
SUBSD X2, X0
// reduce argument
- MOVSD $0.0625, X1
- MULSD X1, X0
+ MULSD $0.0625, X0
// Taylor series evaluation
- MOVSD $2.4801587301587301587e-5, X1
+ MOVSD $T7, X1
MULSD X0, X1
- MOVSD $1.9841269841269841270e-4, X2
- ADDSD X2, X1
+ ADDSD $T6, X1
MULSD X0, X1
- MOVSD $1.3888888888888888889e-3, X2
- ADDSD X2, X1
+ ADDSD $T5, X1
MULSD X0, X1
- MOVSD $8.3333333333333333333e-3, X2
- ADDSD X2, X1
+ ADDSD $T4, X1
MULSD X0, X1
- MOVSD $4.1666666666666666667e-2, X2
- ADDSD X2, X1
+ ADDSD $T3, X1
MULSD X0, X1
- MOVSD $1.6666666666666666667e-1, X2
- ADDSD X2, X1
+ ADDSD $T2, X1
MULSD X0, X1
- MOVSD $0.5, X2
- ADDSD X2, X1
+ ADDSD $T1, X1
MULSD X0, X1
- MOVSD $1.0, X2
- ADDSD X2, X1
+ ADDSD $T0, X1
MULSD X1, X0
MOVSD $2.0, X1
ADDSD X0, X1
@@ -78,27 +82,31 @@ TEXT ·Exp(SB),7,$0
MOVSD $2.0, X1
ADDSD X0, X1
MULSD X1, X0
- MOVSD $1.0, X1
- ADDSD X1, X0
- // return ldexp(fr, exp)
- MOVQ $0x3ff, AX // bias + 1
- ADDQ AX, BX
+ ADDSD $1.0, X0
+ // return fr * 2**exponent
+ MOVL $0x3FF, AX // bias
+ ADDL AX, BX
+ JLE underflow
+ CMPL BX, $0x7FF
+ JGE overflow
+ MOVL $52, CX
+ SHLQ CX, BX
MOVQ BX, X1
- MOVQ $52, AX // shift
- MOVQ AX, X2
- PSLLQ X2, X1
MULSD X1, X0
MOVSD X0, r+8(FP)
RET
-not_finite:
-// test bits for -Inf
- MOVQ x+0(FP), AX
- MOVQ $0xfff0000000000000, BX
- CMPQ BX, AX
- JNE not_neginf
- XORQ AX, AX
+notFinite:
+ // test bits for -Inf
+ MOVQ $NegInf, AX
+ CMPQ AX, BX
+ JNE notNegInf
+ // -Inf, return 0
+underflow: // return 0
+ MOVQ $0, AX
MOVQ AX, r+8(FP)
RET
-not_neginf:
- MOVQ AX, r+8(FP)
+overflow: // return +Inf
+ MOVQ $PosInf, BX
+notNegInf: // NaN or +Inf, return x
+ MOVQ BX, r+8(FP)
RET
diff --git a/src/pkg/math/exp_port.go b/src/pkg/math/exp_port.go
new file mode 100644
index 000000000..071420c24
--- /dev/null
+++ b/src/pkg/math/exp_port.go
@@ -0,0 +1,192 @@
+// Copyright 2009 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
+
+
+// The original C code, the long comment, and the constants
+// below are from FreeBSD's /usr/src/lib/msun/src/e_exp.c
+// and came with this notice. The go code is a simplified
+// version of the original C.
+//
+// ====================================================
+// Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
+//
+// Permission to use, copy, modify, and distribute this
+// software is freely granted, provided that this notice
+// is preserved.
+// ====================================================
+//
+//
+// exp(x)
+// Returns the exponential of x.
+//
+// Method
+// 1. Argument reduction:
+// Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
+// Given x, find r and integer k such that
+//
+// x = k*ln2 + r, |r| <= 0.5*ln2.
+//
+// Here r will be represented as r = hi-lo for better
+// accuracy.
+//
+// 2. Approximation of exp(r) by a special rational function on
+// the interval [0,0.34658]:
+// Write
+// R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
+// We use a special Remes algorithm on [0,0.34658] to generate
+// a polynomial of degree 5 to approximate R. The maximum error
+// of this polynomial approximation is bounded by 2**-59. In
+// other words,
+// R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
+// (where z=r*r, and the values of P1 to P5 are listed below)
+// and
+// | 5 | -59
+// | 2.0+P1*z+...+P5*z - R(z) | <= 2
+// | |
+// The computation of exp(r) thus becomes
+// 2*r
+// exp(r) = 1 + -------
+// R - r
+// r*R1(r)
+// = 1 + r + ----------- (for better accuracy)
+// 2 - R1(r)
+// where
+// 2 4 10
+// R1(r) = r - (P1*r + P2*r + ... + P5*r ).
+//
+// 3. Scale back to obtain exp(x):
+// From step 1, we have
+// exp(x) = 2**k * exp(r)
+//
+// Special cases:
+// exp(INF) is INF, exp(NaN) is NaN;
+// exp(-INF) is 0, and
+// for finite argument, only exp(0)=1 is exact.
+//
+// Accuracy:
+// according to an error analysis, the error is always less than
+// 1 ulp (unit in the last place).
+//
+// Misc. info.
+// For IEEE double
+// if x > 7.09782712893383973096e+02 then exp(x) overflow
+// if x < -7.45133219101941108420e+02 then exp(x) underflow
+//
+// Constants:
+// The hexadecimal values are the intended ones for the following
+// constants. The decimal values may be used, provided that the
+// compiler will convert from decimal to binary accurately enough
+// to produce the hexadecimal values shown.
+
+// Exp returns e**x, the base-e exponential of x.
+//
+// Special cases are:
+// Exp(+Inf) = +Inf
+// Exp(NaN) = NaN
+// Very large values overflow to 0 or +Inf.
+// Very small values underflow to 1.
+func expGo(x float64) float64 {
+ const (
+ Ln2Hi = 6.93147180369123816490e-01
+ Ln2Lo = 1.90821492927058770002e-10
+ Log2e = 1.44269504088896338700e+00
+
+ Overflow = 7.09782712893383973096e+02
+ Underflow = -7.45133219101941108420e+02
+ NearZero = 1.0 / (1 << 28) // 2**-28
+ )
+
+ // TODO(rsc): Remove manual inlining of IsNaN, IsInf
+ // when compiler does it for us
+ // special cases
+ switch {
+ case x != x || x > MaxFloat64: // IsNaN(x) || IsInf(x, 1):
+ return x
+ case x < -MaxFloat64: // IsInf(x, -1):
+ return 0
+ case x > Overflow:
+ return Inf(1)
+ case x < Underflow:
+ return 0
+ case -NearZero < x && x < NearZero:
+ return 1 + x
+ }
+
+ // reduce; computed as r = hi - lo for extra precision.
+ var k int
+ switch {
+ case x < 0:
+ k = int(Log2e*x - 0.5)
+ case x > 0:
+ k = int(Log2e*x + 0.5)
+ }
+ hi := x - float64(k)*Ln2Hi
+ lo := float64(k) * Ln2Lo
+
+ // compute
+ return exp(hi, lo, k)
+}
+
+// Exp2 returns 2**x, the base-2 exponential of x.
+//
+// Special cases are the same as Exp.
+func exp2Go(x float64) float64 {
+ const (
+ Ln2Hi = 6.93147180369123816490e-01
+ Ln2Lo = 1.90821492927058770002e-10
+
+ Overflow = 1.0239999999999999e+03
+ Underflow = -1.0740e+03
+ )
+
+ // TODO: remove manual inlining of IsNaN and IsInf
+ // when compiler does it for us
+ // special cases
+ switch {
+ case x != x || x > MaxFloat64: // IsNaN(x) || IsInf(x, 1):
+ return x
+ case x < -MaxFloat64: // IsInf(x, -1):
+ return 0
+ case x > Overflow:
+ return Inf(1)
+ case x < Underflow:
+ return 0
+ }
+
+ // argument reduction; x = r×lg(e) + k with |r| ≤ ln(2)/2.
+ // computed as r = hi - lo for extra precision.
+ var k int
+ switch {
+ case x > 0:
+ k = int(x + 0.5)
+ case x < 0:
+ k = int(x - 0.5)
+ }
+ t := x - float64(k)
+ hi := t * Ln2Hi
+ lo := -t * Ln2Lo
+
+ // compute
+ return exp(hi, lo, k)
+}
+
+// exp returns e**r × 2**k where r = hi - lo and |r| ≤ ln(2)/2.
+func exp(hi, lo float64, k int) float64 {
+ const (
+ P1 = 1.66666666666666019037e-01 /* 0x3FC55555; 0x5555553E */
+ P2 = -2.77777777770155933842e-03 /* 0xBF66C16C; 0x16BEBD93 */
+ P3 = 6.61375632143793436117e-05 /* 0x3F11566A; 0xAF25DE2C */
+ P4 = -1.65339022054652515390e-06 /* 0xBEBBBD41; 0xC5D26BF1 */
+ P5 = 4.13813679705723846039e-08 /* 0x3E663769; 0x72BEA4D0 */
+ )
+
+ r := hi - lo
+ t := r * r
+ c := r - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))))
+ y := 1 - ((lo - (r*c)/(2-c)) - hi)
+ // TODO(rsc): make sure Ldexp can handle boundary k
+ return Ldexp(y, k)
+}
diff --git a/src/pkg/math/exp_test.go b/src/pkg/math/exp_test.go
new file mode 100644
index 000000000..7381fd5ad
--- /dev/null
+++ b/src/pkg/math/exp_test.go
@@ -0,0 +1,10 @@
+// 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
+
+// Make expGo and exp2Go available for testing.
+
+func ExpGo(x float64) float64 { return expGo(x) }
+func Exp2Go(x float64) float64 { return exp2Go(x) }
diff --git a/src/pkg/math/frexp.go b/src/pkg/math/frexp.go
index b63b508e6..203219c0d 100644
--- a/src/pkg/math/frexp.go
+++ b/src/pkg/math/frexp.go
@@ -19,9 +19,9 @@ func Frexp(f float64) (frac float64, exp int) {
return f, 0
}
x := Float64bits(f)
- exp = int((x>>shift)&mask) - bias
+ exp = int((x>>shift)&mask) - bias + 1
x &^= mask << shift
- x |= bias << shift
+ x |= (-1 + bias) << shift
frac = Float64frombits(x)
return
}
diff --git a/src/pkg/math/hypot_amd64.s b/src/pkg/math/hypot_amd64.s
new file mode 100644
index 000000000..1f691e70e
--- /dev/null
+++ b/src/pkg/math/hypot_amd64.s
@@ -0,0 +1,50 @@
+// 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.
+
+#define PosInf 0x7ff0000000000000
+#define NaN 0x7FF0000000000001
+
+// func Hypot(x, y float64) float64
+TEXT ·Hypot(SB),7,$0
+ // test bits for special cases
+ MOVQ x+0(FP), BX
+ MOVQ $~(1<<63), AX
+ ANDQ AX, BX // x = |x|
+ MOVQ y+8(FP), CX
+ ANDQ AX, CX // y = |y|
+ MOVQ $PosInf, AX
+ CMPQ AX, BX
+ JLE isInfOrNaN
+ CMPQ AX, CX
+ JLE isInfOrNaN
+ // hypot = max * sqrt(1 + (min/max)**2)
+ MOVQ BX, X0
+ MOVQ CX, X1
+ ORQ CX, BX
+ JEQ isZero
+ MOVAPD X0, X2
+ MAXSD X1, X0
+ MINSD X2, X1
+ DIVSD X0, X1
+ MULSD X1, X1
+ ADDSD $1.0, X1
+ SQRTSD X1, X1
+ MULSD X1, X0
+ MOVSD X0, r+16(FP)
+ RET
+isInfOrNaN:
+ CMPQ AX, BX
+ JEQ isInf
+ CMPQ AX, CX
+ JEQ isInf
+ MOVQ $NaN, AX
+ MOVQ AX, r+16(FP) // return NaN
+ RET
+isInf:
+ MOVQ AX, r+16(FP) // return +Inf
+ RET
+isZero:
+ MOVQ $0, AX
+ MOVQ AX, r+16(FP) // return 0
+ RET
diff --git a/src/pkg/math/log.go b/src/pkg/math/log.go
index 02e767b95..39d94512d 100644
--- a/src/pkg/math/log.go
+++ b/src/pkg/math/log.go
@@ -121,11 +121,3 @@ func Log(x float64) float64 {
hfsq := 0.5 * f * f
return k*Ln2Hi - ((hfsq - (s*(hfsq+R) + k*Ln2Lo)) - f)
}
-
-// Log10 returns the decimal logarithm of x.
-// The special cases are the same as for Log.
-func Log10(x float64) float64 { return Log(x) * (1 / Ln10) }
-
-// Log2 returns the binary logarithm of x.
-// The special cases are the same as for Log.
-func Log2(x float64) float64 { return Log(x) * (1 / Ln2) }
diff --git a/src/pkg/math/log10.go b/src/pkg/math/log10.go
new file mode 100644
index 000000000..6d18baae2
--- /dev/null
+++ b/src/pkg/math/log10.go
@@ -0,0 +1,13 @@
+// Copyright 2009 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
+
+// Log10 returns the decimal logarithm of x.
+// The special cases are the same as for Log.
+func Log10(x float64) float64 { return Log(x) * (1 / Ln10) }
+
+// Log2 returns the binary logarithm of x.
+// The special cases are the same as for Log.
+func Log2(x float64) float64 { return Log(x) * (1 / Ln2) }
diff --git a/src/pkg/math/log10_386.s b/src/pkg/math/log10_386.s
new file mode 100644
index 000000000..cc473b424
--- /dev/null
+++ b/src/pkg/math/log10_386.s
@@ -0,0 +1,19 @@
+// 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 Log10(x float64) float64
+TEXT ·Log10(SB),7,$0
+ FLDLG2 // F0=log10(2)
+ FMOVD x+0(FP), F0 // F0=x, F1=log10(2)
+ FYL2X // F0=log10(x)=log2(x)*log10(2)
+ FMOVDP F0, r+8(FP)
+ RET
+
+// func Log2(x float64) float64
+TEXT ·Log2(SB),7,$0
+ FLD1 // F0=1
+ FMOVD x+0(FP), F0 // F0=x, F1=1
+ FYL2X // F0=log2(x)
+ FMOVDP F0, r+8(FP)
+ RET
diff --git a/src/pkg/math/log10_decl.go b/src/pkg/math/log10_decl.go
new file mode 100644
index 000000000..5aec94e1c
--- /dev/null
+++ b/src/pkg/math/log10_decl.go
@@ -0,0 +1,8 @@
+// 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 Log10(x float64) float64
+func Log2(x float64) float64
diff --git a/src/pkg/math/log_386.s b/src/pkg/math/log_386.s
index ae5211e22..6cfbc7605 100644
--- a/src/pkg/math/log_386.s
+++ b/src/pkg/math/log_386.s
@@ -9,19 +9,3 @@ TEXT ·Log(SB),7,$0
FYL2X // F0=log(x)=log2(x)*log(2)
FMOVDP F0, r+8(FP)
RET
-
-// func Log10(x float64) float64
-TEXT ·Log10(SB),7,$0
- FLDLG2 // F0=log10(2)
- FMOVD x+0(FP), F0 // F0=x, F1=log10(2)
- FYL2X // F0=log10(x)=log2(x)*log10(2)
- FMOVDP F0, r+8(FP)
- RET
-
-// func Log2(x float64) float64
-TEXT ·Log2(SB),7,$0
- FLD1 // F0=1
- FMOVD x+0(FP), F0 // F0=x, F1=1
- FYL2X // F0=log2(x)
- FMOVDP F0, r+8(FP)
- RET
diff --git a/src/pkg/math/log_amd64.s b/src/pkg/math/log_amd64.s
new file mode 100644
index 000000000..79e35907c
--- /dev/null
+++ b/src/pkg/math/log_amd64.s
@@ -0,0 +1,109 @@
+// 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.
+
+#define HSqrt2 7.07106781186547524401e-01 // sqrt(2)/2
+#define Ln2Hi 6.93147180369123816490e-01 // 0x3fe62e42fee00000
+#define Ln2Lo 1.90821492927058770002e-10 // 0x3dea39ef35793c76
+#define L1 6.666666666666735130e-01 // 0x3FE5555555555593
+#define L2 3.999999999940941908e-01 // 0x3FD999999997FA04
+#define L3 2.857142874366239149e-01 // 0x3FD2492494229359
+#define L4 2.222219843214978396e-01 // 0x3FCC71C51D8E78AF
+#define L5 1.818357216161805012e-01 // 0x3FC7466496CB03DE
+#define L6 1.531383769920937332e-01 // 0x3FC39A09D078C69F
+#define L7 1.479819860511658591e-01 // 0x3FC2F112DF3E5244
+#define NaN 0x7FF0000000000001
+#define NegInf 0xFFF0000000000000
+#define PosInf 0x7FF0000000000000
+
+// func Log(x float64) float64
+TEXT ·Log(SB),7,$0
+ // test bits for special cases
+ MOVQ x+0(FP), BX
+ MOVQ $~(1<<63), AX // sign bit mask
+ ANDQ BX, AX
+ JEQ isZero
+ MOVQ $0, AX
+ CMPQ AX, BX
+ JGT isNegative
+ MOVQ $PosInf, AX
+ CMPQ AX, BX
+ JLE isInfOrNaN
+ // f1, ki := math.Frexp(x); k := float64(ki)
+ MOVQ BX, X0
+ MOVQ $0x000FFFFFFFFFFFFF, AX
+ MOVQ AX, X2
+ ANDPD X0, X2
+ MOVSD $0.5, X0 // 0x3FE0000000000000
+ ORPD X0, X2 // X2= f1
+ SHRQ $52, BX
+ ANDL $0x7FF, BX
+ SUBL $0x3FE, BX
+ CVTSL2SD BX, X1 // x1= k, x2= f1
+ // if f1 < math.Sqrt2/2 { k -= 1; f1 *= 2 }
+ MOVSD $HSqrt2, X0 // x0= 0.7071, x1= k, x2= f1
+ CMPSD X2, X0, 5 // cmpnlt; x0= 0 or ^0, x1= k, x2 = f1
+ MOVSD $1.0, X3 // x0= 0 or ^0, x1= k, x2 = f1, x3= 1
+ ANDPD X0, X3 // x0= 0 or ^0, x1= k, x2 = f1, x3= 0 or 1
+ SUBSD X3, X1 // x0= 0 or ^0, x1= k, x2 = f1, x3= 0 or 1
+ MOVSD $1.0, X0 // x0= 1, x1= k, x2= f1, x3= 0 or 1
+ ADDSD X0, X3 // x0= 1, x1= k, x2= f1, x3= 1 or 2
+ MULSD X3, X2 // x0= 1, x1= k, x2= f1
+ // f := f1 - 1
+ SUBSD X0, X2 // x1= k, x2= f
+ // s := f / (2 + f)
+ MOVSD $2.0, X0
+ ADDSD X2, X0
+ MOVSD X2, X3
+ DIVSD X0, X3 // x1=k, x2= f, x3= s
+ // s2 := s * s
+ MOVSD X3, X4 // x1= k, x2= f, x3= s
+ MULSD X4, X4 // x1= k, x2= f, x3= s, x4= s2
+ // s4 := s2 * s2
+ MOVSD X4, X5 // x1= k, x2= f, x3= s, x4= s2
+ MULSD X5, X5 // x1= k, x2= f, x3= s, x4= s2, x5= s4
+ // t1 := s2 * (L1 + s4*(L3+s4*(L5+s4*L7)))
+ MOVSD $L7, X6
+ MULSD X5, X6
+ ADDSD $L5, X6
+ MULSD X5, X6
+ ADDSD $L3, X6
+ MULSD X5, X6
+ ADDSD $L1, X6
+ MULSD X6, X4 // x1= k, x2= f, x3= s, x4= t1, x5= s4
+ // t2 := s4 * (L2 + s4*(L4+s4*L6))
+ MOVSD $L6, X6
+ MULSD X5, X6
+ ADDSD $L4, X6
+ MULSD X5, X6
+ ADDSD $L2, X6
+ MULSD X6, X5 // x1= k, x2= f, x3= s, x4= t1, x5= t2
+ // R := t1 + t2
+ ADDSD X5, X4 // x1= k, x2= f, x3= s, x4= R
+ // hfsq := 0.5 * f * f
+ MOVSD $0.5, X0
+ MULSD X2, X0
+ MULSD X2, X0 // x0= hfsq, x1= k, x2= f, x3= s, x4= R
+ // return k*Ln2Hi - ((hfsq - (s*(hfsq+R) + k*Ln2Lo)) - f)
+ ADDSD X0, X4 // x0= hfsq, x1= k, x2= f, x3= s, x4= hfsq+R
+ MULSD X4, X3 // x0= hfsq, x1= k, x2= f, x3= s*(hfsq+R)
+ MOVSD $Ln2Lo, X4
+ MULSD X1, X4 // x4= k*Ln2Lo
+ ADDSD X4, X3 // x0= hfsq, x1= k, x2= f, x3= s*(hfsq+R)+k*Ln2Lo
+ SUBSD X3, X0 // x0= hfsq-(s*(hfsq+R)+k*Ln2Lo), x1= k, x2= f
+ SUBSD X2, X0 // x0= (hfsq-(s*(hfsq+R)+k*Ln2Lo))-f, x1= k
+ MULSD $Ln2Hi, X1 // x0= (hfsq-(s*(hfsq+R)+k*Ln2Lo))-f, x1= k*Ln2Hi
+ SUBSD X0, X1 // x1= k*Ln2Hi-((hfsq-(s*(hfsq+R)+k*Ln2Lo))-f)
+ MOVSD X1, r+8(FP)
+ RET
+isInfOrNaN:
+ MOVQ BX, r+8(FP) // +Inf or NaN, return x
+ RET
+isNegative:
+ MOVQ $NaN, AX
+ MOVQ AX, r+8(FP) // return NaN
+ RET
+isZero:
+ MOVQ $NegInf, AX
+ MOVQ AX, r+8(FP) // return -Inf
+ RET
diff --git a/src/pkg/math/log_decl.go b/src/pkg/math/log_decl.go
index 074b0cdb6..deda305dd 100644
--- a/src/pkg/math/log_decl.go
+++ b/src/pkg/math/log_decl.go
@@ -5,5 +5,3 @@
package math
func Log(x float64) float64
-func Log10(x float64) float64
-func Log2(x float64) float64
diff --git a/src/pkg/math/logb.go b/src/pkg/math/logb.go
index acda15d22..9e4651517 100644
--- a/src/pkg/math/logb.go
+++ b/src/pkg/math/logb.go
@@ -4,7 +4,7 @@
package math
-// Logb(x) returns the binary logarithm of non-zero x.
+// Logb(x) returns the binary exponent of non-zero x.
//
// Special cases are:
// Logb(±Inf) = +Inf
@@ -25,7 +25,7 @@ func Logb(x float64) float64 {
return float64(int((Float64bits(x)>>shift)&mask) - bias)
}
-// Ilogb(x) returns the binary logarithm of non-zero x as an integer.
+// Ilogb(x) returns the binary exponent of non-zero x as an integer.
//
// Special cases are:
// Ilogb(±Inf) = MaxInt32
diff --git a/src/pkg/math/modf.go b/src/pkg/math/modf.go
index ae0c7c887..315174b70 100644
--- a/src/pkg/math/modf.go
+++ b/src/pkg/math/modf.go
@@ -23,9 +23,9 @@ func Modf(f float64) (int float64, frac float64) {
x := Float64bits(f)
e := uint(x>>shift)&mask - bias
- // Keep the top 11+e bits, the integer part; clear the rest.
- if e < 64-11 {
- x &^= 1<<(64-11-e) - 1
+ // Keep the top 12+e bits, the integer part; clear the rest.
+ if e < 64-12 {
+ x &^= 1<<(64-12-e) - 1
}
int = Float64frombits(x)
frac = f - int
diff --git a/src/pkg/math/sincos_amd64.s b/src/pkg/math/sincos_amd64.s
new file mode 100644
index 000000000..18c824e51
--- /dev/null
+++ b/src/pkg/math/sincos_amd64.s
@@ -0,0 +1,143 @@
+// 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.
+
+// The method is based on a paper by Naoki Shibata: "Efficient evaluation
+// methods of elementary functions suitable for SIMD computation", Proc.
+// of International Supercomputing Conference 2010 (ISC'10), pp. 25 -- 32
+// (May 2010). The paper is available at
+// http://www.springerlink.com/content/340228x165742104/
+//
+// The original code and the constants below are from the author's
+// implementation available at http://freshmeat.net/projects/sleef.
+// The README file says, "The software is in public domain.
+// You can use the software without any obligation."
+//
+// This code is a simplified version of the original. The CMPSD
+// instruction, not generated by the compiler, eliminates jumps in the
+// body of the calculation.
+
+#define PosOne 0x3FF0000000000000
+#define PosInf 0x7FF0000000000000
+#define NaN 0x7FF0000000000001
+#define PI4A 0.7853981554508209228515625 // pi/4 split into three parts
+#define PI4B 0.794662735614792836713604629039764404296875e-8
+#define PI4C 0.306161699786838294306516483068750264552437361480769e-16
+#define M4PI 1.273239544735162542821171882678754627704620361328125 // 4/pi
+#define T0 1.0
+#define T1 -8.33333333333333333333333e-02 // (-1.0/12)
+#define T2 2.77777777777777777777778e-03 // (+1.0/360)
+#define T3 -4.96031746031746031746032e-05 // (-1.0/20160)
+#define T4 5.51146384479717813051146e-07 // (+1.0/1814400)
+
+// func Sincos(d float64) (sin, cos float64)
+TEXT ·Sincos(SB),7,$0
+ // test for special cases
+ MOVQ $~(1<<63), DX // sign bit mask
+ MOVQ x+0(FP), BX
+ ANDQ BX, DX
+ JEQ isZero
+ MOVQ $PosInf, AX
+ CMPQ AX, DX
+ JLE isInfOrNaN
+ // Reduce argument
+ MOVQ BX, X7 // x7= d
+ MOVQ DX, X0 // x0= |d|
+ MOVSD $M4PI, X2
+ MULSD X0, X2
+ CVTTSD2SQ X2, BX // bx= q
+ MOVQ $1, AX
+ ANDQ BX, AX
+ ADDQ BX, AX
+ CVTSQ2SD AX, X2
+ MOVSD $PI4A, X3
+ MULSD X2, X3
+ SUBSD X3, X0
+ MOVSD $PI4B, X3
+ MULSD X2, X3
+ SUBSD X3, X0
+ MOVSD $PI4C, X3
+ MULSD X2, X3
+ SUBSD X3, X0
+ MULSD $0.125, X0 // x0= x, x7= d, bx= q
+ // Evaluate Taylor series
+ MULSD X0, X0
+ MOVSD $T4, X2
+ MULSD X0, X2
+ ADDSD $T3, X2
+ MULSD X0, X2
+ ADDSD $T2, X2
+ MULSD X0, X2
+ ADDSD $T1, X2
+ MULSD X0, X2
+ ADDSD $T0, X2
+ MULSD X2, X0 // x0= x, x7= d, bx= q
+ // Apply double angle formula
+ MOVSD $4.0, X2
+ SUBSD X0, X2
+ MULSD X2, X0
+ MOVSD $4.0, X2
+ SUBSD X0, X2
+ MULSD X2, X0
+ MOVSD $4.0, X2
+ SUBSD X0, X2
+ MULSD X2, X0
+ MULSD $0.5, X0 // x0= x, x7= d, bx= q
+ // sin = sqrt((2 - x) * x)
+ MOVSD $2.0, X2
+ SUBSD X0, X2
+ MULSD X0, X2
+ SQRTSD X2, X2 // x0= x, x2= z, x7= d, bx= q
+ // cos = 1 - x
+ MOVSD $1.0, X1
+ SUBSD X0, X1 // x1= x, x2= z, x7= d, bx= q
+ // if ((q + 1) & 2) != 0 { sin, cos = cos, sin }
+ MOVQ $1, DX
+ ADDQ BX, DX
+ MOVQ $2, AX
+ ANDQ AX, DX
+ MOVQ DX, X0
+ MOVSD $0.0, X3
+ CMPSD X0, X3, 0 // cmpeq; x1= x, x2= z, x3 = y, x7= d, bx= q
+ // sin = (y & z) | (^y & x)
+ MOVAPD X2, X0
+ ANDPD X3, X0 // x0= sin
+ MOVAPD X3, X4
+ ANDNPD X1, X4
+ ORPD X4, X0 // x0= sin, x1= x, x2= z, x3= y, x7= d, bx= q
+ // cos = (y & x) | (^y & z)
+ ANDPD X3, X1 // x1= cos
+ ANDNPD X2, X3
+ ORPD X3, X1 // x0= sin, x1= cos, x7= d, bx= q
+ // if ((q & 4) != 0) != (d < 0) { sin = -sin }
+ MOVQ BX, AX
+ MOVQ $61, CX
+ SHLQ CX, AX
+ MOVQ AX, X3
+ XORPD X7, X3
+ MOVQ $(1<<63), AX
+ MOVQ AX, X2 // x2= -0.0
+ ANDPD X2, X3
+ ORPD X3, X0 // x0= sin, x1= cos, x2= -0.0, bx= q
+ // if ((q + 2) & 4) != 0 { cos = -cos }
+ MOVQ $2, AX
+ ADDQ AX, BX
+ MOVQ $61, CX
+ SHLQ CX, BX
+ MOVQ BX, X3
+ ANDPD X2, X3
+ ORPD X3, X1 // x0= sin, x1= cos
+ // return (sin, cos)
+ MOVSD X0, sin+8(FP)
+ MOVSD X1, cos+16(FP)
+ RET
+isZero: // return (±0.0, 1.0)
+ MOVQ BX, sin+8(FP)
+ MOVQ $PosOne, AX
+ MOVQ AX, cos+16(FP)
+ RET
+isInfOrNaN: // return (NaN, NaN)
+ MOVQ $NaN, AX
+ MOVQ AX, sin+8(FP)
+ MOVQ AX, cos+16(FP)
+ RET
diff --git a/src/pkg/math/sqrt_port.go b/src/pkg/math/sqrt_port.go
index 8d821b559..6f35a383d 100644
--- a/src/pkg/math/sqrt_port.go
+++ b/src/pkg/math/sqrt_port.go
@@ -113,7 +113,7 @@ func sqrtGo(x float64) float64 {
}
exp++
}
- exp -= bias + 1 // unbias exponent
+ exp -= bias // unbias exponent
ix &^= mask << shift
ix |= 1 << shift
if exp&1 == 1 { // odd exp, double x to make it even
@@ -138,6 +138,6 @@ func sqrtGo(x float64) float64 {
if ix != 0 { // remainder, result not exact
q += q & 1 // round according to extra bit
}
- ix = q>>1 + uint64(exp+bias)<<shift // significand + biased exponent
+ ix = q>>1 + uint64(exp-1+bias)<<shift // significand + biased exponent
return Float64frombits(ix)
}
diff --git a/src/pkg/math/tan.go b/src/pkg/math/tan.go
index 842ac6438..a36ebbf44 100644
--- a/src/pkg/math/tan.go
+++ b/src/pkg/math/tan.go
@@ -54,7 +54,7 @@ func Tan(x float64) float64 {
if flag {
if temp == 0 {
- panic(NaN())
+ return NaN()
}
temp = 1 / temp
}