summaryrefslogtreecommitdiff
path: root/libgo/go/math
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2012-01-12 01:31:45 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2012-01-12 01:31:45 +0000
commit26ae0101ebafafea33beadccea3056f4b5e135e8 (patch)
tree86a3b8019380d5fad53258c4baba3dd9e1e7c736 /libgo/go/math
parentc8142b20a95ae9c6bd0bac8c5a545b27402836fe (diff)
downloadgcc-26ae0101ebafafea33beadccea3056f4b5e135e8.tar.gz
libgo: Update to weekly.2011-12-14.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183118 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/math')
-rw-r--r--libgo/go/math/abs.go5
-rw-r--r--libgo/go/math/abs_decl.go7
-rw-r--r--libgo/go/math/acosh.go1
-rw-r--r--libgo/go/math/all_test.go114
-rw-r--r--libgo/go/math/asin.go14
-rw-r--r--libgo/go/math/asinh.go1
-rw-r--r--libgo/go/math/atan.go5
-rw-r--r--libgo/go/math/atan2.go5
-rw-r--r--libgo/go/math/atanh.go3
-rw-r--r--libgo/go/math/big/nat.go2
-rw-r--r--libgo/go/math/const.go2
-rw-r--r--libgo/go/math/dim.go61
-rw-r--r--libgo/go/math/dim_decl.go9
-rw-r--r--libgo/go/math/exp.go188
-rw-r--r--libgo/go/math/exp2.go10
-rw-r--r--libgo/go/math/exp_port.go191
-rw-r--r--libgo/go/math/exp_test.go10
-rw-r--r--libgo/go/math/expm1.go5
-rw-r--r--libgo/go/math/export_test.go11
-rw-r--r--libgo/go/math/floor.go22
-rw-r--r--libgo/go/math/frexp.go4
-rw-r--r--libgo/go/math/hypot.go4
-rw-r--r--libgo/go/math/hypot_port.go63
-rw-r--r--libgo/go/math/hypot_test.go9
-rw-r--r--libgo/go/math/ldexp.go5
-rw-r--r--libgo/go/math/log.go5
-rw-r--r--libgo/go/math/log10.go18
-rw-r--r--libgo/go/math/log10_decl.go8
-rw-r--r--libgo/go/math/log1p.go5
-rw-r--r--libgo/go/math/mod.go12
-rw-r--r--libgo/go/math/mod_decl.go7
-rw-r--r--libgo/go/math/modf.go4
-rw-r--r--libgo/go/math/nextafter.go6
-rw-r--r--libgo/go/math/pow10.go4
-rw-r--r--libgo/go/math/remainder.go10
-rw-r--r--libgo/go/math/sin.go12
-rw-r--r--libgo/go/math/sincos.go4
-rw-r--r--libgo/go/math/sqrt.go131
-rw-r--r--libgo/go/math/sqrt_decl.go7
-rw-r--r--libgo/go/math/sqrt_port.go147
-rw-r--r--libgo/go/math/sqrt_test.go9
-rw-r--r--libgo/go/math/tan.go5
42 files changed, 643 insertions, 502 deletions
diff --git a/libgo/go/math/abs.go b/libgo/go/math/abs.go
index 4c6297c6f33..6818998ee91 100644
--- a/libgo/go/math/abs.go
+++ b/libgo/go/math/abs.go
@@ -9,7 +9,12 @@ package math
// Special cases are:
// Abs(±Inf) = +Inf
// Abs(NaN) = NaN
+func libc_fabs(float64) float64 __asm__("fabs")
func Abs(x float64) float64 {
+ return libc_fabs(x)
+}
+
+func abs(x float64) float64 {
switch {
case x < 0:
return -x
diff --git a/libgo/go/math/abs_decl.go b/libgo/go/math/abs_decl.go
deleted file mode 100644
index 6be9305ac50..00000000000
--- a/libgo/go/math/abs_decl.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// 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 Abs(x float64) float64
diff --git a/libgo/go/math/acosh.go b/libgo/go/math/acosh.go
index 7e8740b89bd..8d556377f59 100644
--- a/libgo/go/math/acosh.go
+++ b/libgo/go/math/acosh.go
@@ -36,6 +36,7 @@ package math
// Acosh(x) calculates the inverse hyperbolic cosine of x.
//
// Special cases are:
+// Acosh(+Inf) = +Inf
// Acosh(x) = NaN if x < 1
// Acosh(NaN) = NaN
func Acosh(x float64) float64 {
diff --git a/libgo/go/math/all_test.go b/libgo/go/math/all_test.go
index 7e63023a1c4..0a3cb0315d2 100644
--- a/libgo/go/math/all_test.go
+++ b/libgo/go/math/all_test.go
@@ -958,6 +958,75 @@ var fabsSC = []float64{
NaN(),
}
+var vffdimSC = [][2]float64{
+ {Inf(-1), Inf(-1)},
+ {Inf(-1), Inf(1)},
+ {Inf(-1), NaN()},
+ {Copysign(0, -1), Copysign(0, -1)},
+ {Copysign(0, -1), 0},
+ {0, Copysign(0, -1)},
+ {0, 0},
+ {Inf(1), Inf(-1)},
+ {Inf(1), Inf(1)},
+ {Inf(1), NaN()},
+ {NaN(), Inf(-1)},
+ {NaN(), Copysign(0, -1)},
+ {NaN(), 0},
+ {NaN(), Inf(1)},
+ {NaN(), NaN()},
+}
+var fdimSC = []float64{
+ NaN(),
+ 0,
+ NaN(),
+ 0,
+ 0,
+ 0,
+ 0,
+ Inf(1),
+ NaN(),
+ NaN(),
+ NaN(),
+ NaN(),
+ NaN(),
+ NaN(),
+ NaN(),
+}
+var fmaxSC = []float64{
+ Inf(-1),
+ Inf(1),
+ NaN(),
+ Copysign(0, -1),
+ 0,
+ 0,
+ 0,
+ Inf(1),
+ Inf(1),
+ Inf(1),
+ NaN(),
+ NaN(),
+ NaN(),
+ Inf(1),
+ NaN(),
+}
+var fminSC = []float64{
+ Inf(-1),
+ Inf(-1),
+ Inf(-1),
+ Copysign(0, -1),
+ Copysign(0, -1),
+ Copysign(0, -1),
+ 0,
+ Inf(-1),
+ Inf(1),
+ NaN(),
+ Inf(-1),
+ NaN(),
+ NaN(),
+ NaN(),
+ NaN(),
+}
+
var vffmodSC = [][2]float64{
{Inf(-1), Inf(-1)},
{Inf(-1), -Pi},
@@ -1259,12 +1328,26 @@ var modfSC = [][2]float64{
}
var vfnextafterSC = [][2]float64{
+ {0, 0},
+ {0, Copysign(0, -1)},
+ {0, -1},
{0, NaN()},
+ {Copysign(0, -1), 1},
+ {Copysign(0, -1), 0},
+ {Copysign(0, -1), Copysign(0, -1)},
+ {Copysign(0, -1), -1},
{NaN(), 0},
{NaN(), NaN()},
}
var nextafterSC = []float64{
+ 0,
+ 0,
+ -4.9406564584124654418e-324, // Float64frombits(0x8000000000000001)
NaN(),
+ 4.9406564584124654418e-324, // Float64frombits(0x0000000000000001)
+ Copysign(0, -1),
+ Copysign(0, -1),
+ -4.9406564584124654418e-324, // Float64frombits(0x8000000000000001)
NaN(),
NaN(),
}
@@ -1875,6 +1958,11 @@ func TestDim(t *testing.T) {
t.Errorf("Dim(%g, %g) = %g, want %g", vf[i], 0.0, f, fdim[i])
}
}
+ for i := 0; i < len(vffdimSC); i++ {
+ if f := Dim(vffdimSC[i][0], vffdimSC[i][1]); !alike(fdimSC[i], f) {
+ t.Errorf("Dim(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fdimSC[i])
+ }
+ }
}
func TestFloor(t *testing.T) {
@@ -1896,6 +1984,11 @@ func TestMax(t *testing.T) {
t.Errorf("Max(%g, %g) = %g, want %g", vf[i], ceil[i], f, ceil[i])
}
}
+ for i := 0; i < len(vffdimSC); i++ {
+ if f := Max(vffdimSC[i][0], vffdimSC[i][1]); !alike(fmaxSC[i], f) {
+ t.Errorf("Max(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fmaxSC[i])
+ }
+ }
}
func TestMin(t *testing.T) {
@@ -1904,6 +1997,11 @@ func TestMin(t *testing.T) {
t.Errorf("Min(%g, %g) = %g, want %g", vf[i], floor[i], f, floor[i])
}
}
+ for i := 0; i < len(vffdimSC); i++ {
+ if f := Min(vffdimSC[i][0], vffdimSC[i][1]); !alike(fminSC[i], f) {
+ t.Errorf("Min(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fminSC[i])
+ }
+ }
}
func TestMod(t *testing.T) {
@@ -1964,6 +2062,20 @@ func TestHypot(t *testing.T) {
}
}
+func TestHypotGo(t *testing.T) {
+ for i := 0; i < len(vf); i++ {
+ a := Abs(1e200 * tanh[i] * Sqrt(2))
+ if f := HypotGo(1e200*tanh[i], 1e200*tanh[i]); !veryclose(a, f) {
+ t.Errorf("HypotGo(%g, %g) = %g, want %g", 1e200*tanh[i], 1e200*tanh[i], f, a)
+ }
+ }
+ for i := 0; i < len(vfhypotSC); i++ {
+ if f := HypotGo(vfhypotSC[i][0], vfhypotSC[i][1]); !alike(hypotSC[i], f) {
+ t.Errorf("HypotGo(%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++ {
a := frexp[i].i - 1 // adjust because fr in the interval [½, 1)
@@ -2175,7 +2287,7 @@ func TestNextafter(t *testing.T) {
t.Errorf("Nextafter(%g, %g) = %g want %g", vf[i], 10.0, f, nextafter[i])
}
}
- for i := 0; i < len(vfmodfSC); i++ {
+ for i := 0; i < len(vfnextafterSC); i++ {
if f := Nextafter(vfnextafterSC[i][0], vfnextafterSC[i][1]); !alike(nextafterSC[i], f) {
t.Errorf("Nextafter(%g, %g) = %g want %g", vfnextafterSC[i][0], vfnextafterSC[i][1], f, nextafterSC[i])
}
diff --git a/libgo/go/math/asin.go b/libgo/go/math/asin.go
index 0a0b0a11cb4..d67f32a5097 100644
--- a/libgo/go/math/asin.go
+++ b/libgo/go/math/asin.go
@@ -16,7 +16,12 @@ package math
// Special cases are:
// Asin(±0) = ±0
// Asin(x) = NaN if x < -1 or x > 1
+func libc_asin(float64) float64 __asm__("asin")
func Asin(x float64) float64 {
+ return libc_asin(x)
+}
+
+func asin(x float64) float64 {
if x == 0 {
return x // special case
}
@@ -46,4 +51,11 @@ func Asin(x float64) float64 {
//
// Special case is:
// Acos(x) = NaN if x < -1 or x > 1
-func Acos(x float64) float64 { return Pi/2 - Asin(x) }
+func libc_acos(float64) float64 __asm__("acos")
+func Acos(x float64) float64 {
+ return libc_acos(x)
+}
+
+func acos(x float64) float64 {
+ return Pi/2 - Asin(x)
+}
diff --git a/libgo/go/math/asinh.go b/libgo/go/math/asinh.go
index d6979463d65..f786dd9f8f0 100644
--- a/libgo/go/math/asinh.go
+++ b/libgo/go/math/asinh.go
@@ -33,6 +33,7 @@ package math
// Asinh(x) calculates the inverse hyperbolic sine of x.
//
// Special cases are:
+// Asinh(±0) = ±0
// Asinh(±Inf) = ±Inf
// Asinh(NaN) = NaN
func Asinh(x float64) float64 {
diff --git a/libgo/go/math/atan.go b/libgo/go/math/atan.go
index 9d4ec2f72db..ff52cf3d367 100644
--- a/libgo/go/math/atan.go
+++ b/libgo/go/math/atan.go
@@ -51,7 +51,12 @@ func satan(arg float64) float64 {
// Special cases are:
// Atan(±0) = ±0
// Atan(±Inf) = ±Pi/2
+func libc_atan(float64) float64 __asm__("atan")
func Atan(x float64) float64 {
+ return libc_atan(x)
+}
+
+func atan(x float64) float64 {
if x == 0 {
return x
}
diff --git a/libgo/go/math/atan2.go b/libgo/go/math/atan2.go
index 49d4bdd7191..7260f986fad 100644
--- a/libgo/go/math/atan2.go
+++ b/libgo/go/math/atan2.go
@@ -26,7 +26,12 @@ package math
// Atan2(y<0, -Inf) = -Pi
// Atan2(+Inf, x) = +Pi/2
// Atan2(-Inf, x) = -Pi/2
+func libc_atan2(float64, float64) float64 __asm__("atan2")
func Atan2(y, x float64) float64 {
+ return libc_atan2(y, x)
+}
+
+func atan2(y, x float64) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
// special cases
diff --git a/libgo/go/math/atanh.go b/libgo/go/math/atanh.go
index ed38fcac665..e150673c700 100644
--- a/libgo/go/math/atanh.go
+++ b/libgo/go/math/atanh.go
@@ -39,9 +39,10 @@ package math
// Atanh(x) calculates the inverse hyperbolic tangent of x.
//
// Special cases are:
-// Atanh(x) = NaN if x < -1 or x > 1
// Atanh(1) = +Inf
+// Atanh(±0) = ±0
// Atanh(-1) = -Inf
+// Atanh(x) = NaN if x < -1 or x > 1
// Atanh(NaN) = NaN
func Atanh(x float64) float64 {
const NearZero = 1.0 / (1 << 28) // 2**-28
diff --git a/libgo/go/math/big/nat.go b/libgo/go/math/big/nat.go
index 680445dc9a7..ead1a881a6a 100644
--- a/libgo/go/math/big/nat.go
+++ b/libgo/go/math/big/nat.go
@@ -592,7 +592,7 @@ func (x nat) bitLen() int {
const MaxBase = 'z' - 'a' + 10 + 1 // = hexValue('z') + 1
func hexValue(ch rune) Word {
- d := MaxBase + 1 // illegal base
+ d := int(MaxBase + 1) // illegal base
switch {
case '0' <= ch && ch <= '9':
d = int(ch - '0')
diff --git a/libgo/go/math/const.go b/libgo/go/math/const.go
index a108d3e294d..282561f98bb 100644
--- a/libgo/go/math/const.go
+++ b/libgo/go/math/const.go
@@ -49,5 +49,3 @@ const (
MaxUint32 = 1<<32 - 1
MaxUint64 = 1<<64 - 1
)
-
-// BUG(rsc): The manual should define the special cases for all of these functions.
diff --git a/libgo/go/math/dim.go b/libgo/go/math/dim.go
index d2eb52f3bf1..24a84e6d03b 100644
--- a/libgo/go/math/dim.go
+++ b/libgo/go/math/dim.go
@@ -5,15 +5,45 @@
package math
// Dim returns the maximum of x-y or 0.
+//
+// Special cases are:
+// Dim(+Inf, +Inf) = NaN
+// Dim(-Inf, -Inf) = NaN
+// Dim(x, NaN) = Dim(NaN, x) = NaN
func Dim(x, y float64) float64 {
- if x > y {
- return x - y
- }
- return 0
+ return dim(x, y)
+}
+
+func dim(x, y float64) float64 {
+ return max(x-y, 0)
}
// Max returns the larger of x or y.
+//
+// Special cases are:
+// Max(x, +Inf) = Max(+Inf, x) = +Inf
+// Max(x, NaN) = Max(NaN, x) = NaN
+// Max(+0, ±0) = Max(±0, +0) = +0
+// Max(-0, -0) = -0
func Max(x, y float64) float64 {
+ return max(x, y)
+}
+
+func max(x, y float64) float64 {
+ // TODO(rsc): Remove manual inlining of IsNaN, IsInf
+ // when compiler does it for us
+ // special cases
+ switch {
+ case x > MaxFloat64 || y > MaxFloat64: // IsInf(x, 1) || IsInf(y, 1):
+ return Inf(1)
+ case x != x || y != y: // IsNaN(x) || IsNaN(y):
+ return NaN()
+ case x == 0 && x == y:
+ if Signbit(x) {
+ return y
+ }
+ return x
+ }
if x > y {
return x
}
@@ -21,7 +51,30 @@ func Max(x, y float64) float64 {
}
// Min returns the smaller of x or y.
+//
+// Special cases are:
+// Min(x, -Inf) = Min(-Inf, x) = -Inf
+// Min(x, NaN) = Min(NaN, x) = NaN
+// Min(-0, ±0) = Min(±0, -0) = -0
func Min(x, y float64) float64 {
+ return min(x, y)
+}
+
+func min(x, y float64) float64 {
+ // TODO(rsc): Remove manual inlining of IsNaN, IsInf
+ // when compiler does it for us
+ // special cases
+ switch {
+ case x < -MaxFloat64 || y < -MaxFloat64: // IsInf(x, -1) || IsInf(y, -1):
+ return Inf(-1)
+ case x != x || y != y: // IsNaN(x) || IsNaN(y):
+ return NaN()
+ case x == 0 && x == y:
+ if Signbit(x) {
+ return x
+ }
+ return y
+ }
if x < y {
return x
}
diff --git a/libgo/go/math/dim_decl.go b/libgo/go/math/dim_decl.go
deleted file mode 100644
index 196f84fd793..00000000000
--- a/libgo/go/math/dim_decl.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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 Dim(x, y float64) float64
-func Max(x, y float64) float64
-func Min(x, y float64) float64
diff --git a/libgo/go/math/exp.go b/libgo/go/math/exp.go
index c519c2cb6b6..2db691f38f1 100644
--- a/libgo/go/math/exp.go
+++ b/libgo/go/math/exp.go
@@ -11,4 +11,190 @@ package math
// Exp(NaN) = NaN
// Very large values overflow to 0 or +Inf.
// Very small values underflow to 1.
-func Exp(x float64) float64 { return expGo(x) }
+func libc_exp(float64) float64 __asm__("exp")
+func Exp(x float64) float64 {
+ return libc_exp(x)
+}
+
+// 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.
+
+func exp(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 expmulti(hi, lo, k)
+}
+
+// Exp2 returns 2**x, the base-2 exponential of x.
+//
+// Special cases are the same as Exp.
+func Exp2(x float64) float64 {
+ return exp2(x)
+}
+
+func exp2(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 expmulti(hi, lo, k)
+}
+
+// exp1 returns e**r × 2**k where r = hi - lo and |r| ≤ ln(2)/2.
+func expmulti(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/libgo/go/math/exp2.go b/libgo/go/math/exp2.go
deleted file mode 100644
index 1cface9d360..00000000000
--- a/libgo/go/math/exp2.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// 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
-
-// Exp2 returns 2**x, the base-2 exponential of x.
-//
-// Special cases are the same as Exp.
-func Exp2(x float64) float64 { return exp2Go(x) }
diff --git a/libgo/go/math/exp_port.go b/libgo/go/math/exp_port.go
deleted file mode 100644
index 618c31a5d11..00000000000
--- a/libgo/go/math/exp_port.go
+++ /dev/null
@@ -1,191 +0,0 @@
-// 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/libgo/go/math/exp_test.go b/libgo/go/math/exp_test.go
deleted file mode 100644
index 7381fd5ad34..00000000000
--- a/libgo/go/math/exp_test.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// 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/libgo/go/math/expm1.go b/libgo/go/math/expm1.go
index e9f833140b5..5bffdb323a4 100644
--- a/libgo/go/math/expm1.go
+++ b/libgo/go/math/expm1.go
@@ -121,7 +121,12 @@ package math
// Expm1(-Inf) = -1
// Expm1(NaN) = NaN
// Very large values overflow to -1 or +Inf.
+func libc_expm1(float64) float64 __asm__("expm1")
func Expm1(x float64) float64 {
+ return libc_expm1(x)
+}
+
+func expm1(x float64) float64 {
const (
Othreshold = 7.09782712893383973096e+02 // 0x40862E42FEFA39EF
Ln2X56 = 3.88162421113569373274e+01 // 0x4043687a9f1af2b1
diff --git a/libgo/go/math/export_test.go b/libgo/go/math/export_test.go
new file mode 100644
index 00000000000..02992d70e84
--- /dev/null
+++ b/libgo/go/math/export_test.go
@@ -0,0 +1,11 @@
+// Copyright 2011 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
+
+// Export internal functions for testing.
+var ExpGo = exp
+var Exp2Go = exp2
+var HypotGo = hypot
+var SqrtGo = sqrt
diff --git a/libgo/go/math/floor.go b/libgo/go/math/floor.go
index 8de4d7e2ce6..4d5f4a42707 100644
--- a/libgo/go/math/floor.go
+++ b/libgo/go/math/floor.go
@@ -7,9 +7,15 @@ package math
// Floor returns the greatest integer value less than or equal to x.
//
// Special cases are:
+// Floor(±0) = ±0
// Floor(±Inf) = ±Inf
// Floor(NaN) = NaN
+func libc_floor(float64) float64 __asm__("floor")
func Floor(x float64) float64 {
+ return libc_floor(x)
+}
+
+func floor(x float64) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
if x == 0 || x != x || x > MaxFloat64 || x < -MaxFloat64 { // x == 0 || IsNaN(x) || IsInf(x, 0)
@@ -29,16 +35,30 @@ func Floor(x float64) float64 {
// Ceil returns the least integer value greater than or equal to x.
//
// Special cases are:
+// Ceil(±0) = ±0
// Ceil(±Inf) = ±Inf
// Ceil(NaN) = NaN
-func Ceil(x float64) float64 { return -Floor(-x) }
+func libc_ceil(float64) float64 __asm__("ceil")
+func Ceil(x float64) float64 {
+ return libc_ceil(x)
+}
+
+func ceil(x float64) float64 {
+ return -Floor(-x)
+}
// Trunc returns the integer value of x.
//
// Special cases are:
+// Trunc(±0) = ±0
// Trunc(±Inf) = ±Inf
// Trunc(NaN) = NaN
+func libc_trunc(float64) float64 __asm__("trunc")
func Trunc(x float64) float64 {
+ return libc_trunc(x)
+}
+
+func trunc(x float64) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
if x == 0 || x != x || x > MaxFloat64 || x < -MaxFloat64 { // x == 0 || IsNaN(x) || IsInf(x, 0)
diff --git a/libgo/go/math/frexp.go b/libgo/go/math/frexp.go
index 867b78f3648..6b928e714c5 100644
--- a/libgo/go/math/frexp.go
+++ b/libgo/go/math/frexp.go
@@ -14,6 +14,10 @@ package math
// Frexp(±Inf) = ±Inf, 0
// Frexp(NaN) = NaN, 0
func Frexp(f float64) (frac float64, exp int) {
+ return frexp(f)
+}
+
+func frexp(f float64) (frac float64, exp int) {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
// special cases
diff --git a/libgo/go/math/hypot.go b/libgo/go/math/hypot.go
index ecd115d9ef8..5c7c3a832b3 100644
--- a/libgo/go/math/hypot.go
+++ b/libgo/go/math/hypot.go
@@ -15,6 +15,10 @@ package math
// Hypot(p, q) = +Inf if p or q is infinite
// Hypot(p, q) = NaN if p or q is NaN
func Hypot(p, q float64) float64 {
+ return hypot(p, q)
+}
+
+func hypot(p, q float64) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
// special cases
diff --git a/libgo/go/math/hypot_port.go b/libgo/go/math/hypot_port.go
deleted file mode 100644
index 27f335ba2de..00000000000
--- a/libgo/go/math/hypot_port.go
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2009-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
-
-/*
- Hypot -- sqrt(p*p + q*q), but overflows only if the result does.
- See:
- Cleve Moler and Donald Morrison,
- Replacing Square Roots by Pythagorean Sums
- IBM Journal of Research and Development,
- Vol. 27, Number 6, pp. 577-581, Nov. 1983
-*/
-
-// Hypot computes Sqrt(p*p + q*q), taking care to avoid
-// unnecessary overflow and underflow.
-//
-// Special cases are:
-// Hypot(p, q) = +Inf if p or q is infinite
-// Hypot(p, q) = NaN if p or q is NaN
-func hypotGo(p, q float64) float64 {
- // TODO(rsc): Remove manual inlining of IsNaN, IsInf
- // when compiler does it for us
- // special cases
- switch {
- case p < -MaxFloat64 || p > MaxFloat64 || q < -MaxFloat64 || q > MaxFloat64: // IsInf(p, 0) || IsInf(q, 0):
- return Inf(1)
- case p != p || q != q: // IsNaN(p) || IsNaN(q):
- return NaN()
- }
- if p < 0 {
- p = -p
- }
- if q < 0 {
- q = -q
- }
-
- if p < q {
- p, q = q, p
- }
-
- if p == 0 {
- return 0
- }
-
- pfac := p
- q = q / p
- r := q
- p = 1
- for {
- r = r * r
- s := r + 4
- if s == 4 {
- return p * pfac
- }
- r = r / s
- p = p + 2*r*p
- q = q * r
- r = q / p
- }
- panic("unreachable")
-}
diff --git a/libgo/go/math/hypot_test.go b/libgo/go/math/hypot_test.go
deleted file mode 100644
index 85ce1d404d6..00000000000
--- a/libgo/go/math/hypot_test.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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 hypotGo available for testing.
-
-func HypotGo(x, y float64) float64 { return hypotGo(x, y) }
diff --git a/libgo/go/math/ldexp.go b/libgo/go/math/ldexp.go
index 96c95cad4ae..4601cd58cbb 100644
--- a/libgo/go/math/ldexp.go
+++ b/libgo/go/math/ldexp.go
@@ -11,7 +11,12 @@ package math
// Ldexp(±0, exp) = ±0
// Ldexp(±Inf, exp) = ±Inf
// Ldexp(NaN, exp) = NaN
+func libc_ldexp(float64, int) float64 __asm__("ldexp")
func Ldexp(frac float64, exp int) float64 {
+ return libc_ldexp(frac, exp)
+}
+
+func ldexp(frac float64, exp int) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
// special cases
diff --git a/libgo/go/math/log.go b/libgo/go/math/log.go
index a786c8ce3ab..f06611dfdd2 100644
--- a/libgo/go/math/log.go
+++ b/libgo/go/math/log.go
@@ -77,7 +77,12 @@ package math
// Log(0) = -Inf
// Log(x < 0) = NaN
// Log(NaN) = NaN
+func libc_log(float64) float64 __asm__("log")
func Log(x float64) float64 {
+ return libc_log(x)
+}
+
+func log(x float64) float64 {
const (
Ln2Hi = 6.93147180369123816490e-01 /* 3fe62e42 fee00000 */
Ln2Lo = 1.90821492927058770002e-10 /* 3dea39ef 35793c76 */
diff --git a/libgo/go/math/log10.go b/libgo/go/math/log10.go
index 6d18baae2a9..5204492b3c4 100644
--- a/libgo/go/math/log10.go
+++ b/libgo/go/math/log10.go
@@ -6,8 +6,22 @@ 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) }
+func libc_log10(float64) float64 __asm__("log10")
+func Log10(x float64) float64 {
+ return libc_log10(x)
+}
+
+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) }
+func libc_log2(float64) float64 __asm__("log2")
+func Log2(x float64) float64 {
+ return libc_log2(x)
+}
+
+func log2(x float64) float64 {
+ return Log(x) * (1 / Ln2)
+}
diff --git a/libgo/go/math/log10_decl.go b/libgo/go/math/log10_decl.go
deleted file mode 100644
index 5aec94e1c4f..00000000000
--- a/libgo/go/math/log10_decl.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// 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/libgo/go/math/log1p.go b/libgo/go/math/log1p.go
index e8914a1d053..39c1b40e802 100644
--- a/libgo/go/math/log1p.go
+++ b/libgo/go/math/log1p.go
@@ -92,7 +92,12 @@ package math
// Log1p(-1) = -Inf
// Log1p(x < -1) = NaN
// Log1p(NaN) = NaN
+func libc_log1p(float64) float64 __asm__("log1p")
func Log1p(x float64) float64 {
+ return libc_log1p(x)
+}
+
+func log1p(x float64) float64 {
const (
Sqrt2M1 = 4.142135623730950488017e-01 // Sqrt(2)-1 = 0x3fda827999fcef34
Sqrt2HalfM1 = -2.928932188134524755992e-01 // Sqrt(2)/2-1 = 0xbfd2bec333018866
diff --git a/libgo/go/math/mod.go b/libgo/go/math/mod.go
index 6b16abe5d13..347da70f832 100644
--- a/libgo/go/math/mod.go
+++ b/libgo/go/math/mod.go
@@ -13,9 +13,17 @@ package math
// sign agrees with that of x.
//
// Special cases are:
-// if x is not finite, Mod returns NaN
-// if y is 0 or NaN, Mod returns NaN
+// Mod(±Inf, y) = NaN
+// Mod(NaN, y) = NaN
+// Mod(x, 0) = NaN
+// Mod(x, ±Inf) = x
+// Mod(x, NaN) = NaN
+func libc_fmod(float64, float64) float64 __asm__("fmod")
func Mod(x, y float64) float64 {
+ return libc_fmod(x, y)
+}
+
+func mod(x, y float64) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us.
if y == 0 || x > MaxFloat64 || x < -MaxFloat64 || x != x || y != y { // y == 0 || IsInf(x, 0) || IsNaN(x) || IsNan(y)
diff --git a/libgo/go/math/mod_decl.go b/libgo/go/math/mod_decl.go
deleted file mode 100644
index d5047a754a8..00000000000
--- a/libgo/go/math/mod_decl.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// 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 Mod(x, y float64) float64
diff --git a/libgo/go/math/modf.go b/libgo/go/math/modf.go
index 34889e0c0af..ecec4b756c7 100644
--- a/libgo/go/math/modf.go
+++ b/libgo/go/math/modf.go
@@ -11,6 +11,10 @@ package math
// Modf(±Inf) = ±Inf, NaN
// Modf(NaN) = NaN, NaN
func Modf(f float64) (int float64, frac float64) {
+ return modf(f)
+}
+
+func modf(f float64) (int float64, frac float64) {
if f < 1 {
if f < 0 {
int, frac = Modf(-f)
diff --git a/libgo/go/math/nextafter.go b/libgo/go/math/nextafter.go
index 86114340c1e..e7723baacfb 100644
--- a/libgo/go/math/nextafter.go
+++ b/libgo/go/math/nextafter.go
@@ -8,8 +8,8 @@ package math
// If x == y, then x is returned.
//
// Special cases are:
-// Nextafter(NaN, y) = NaN
-// Nextafter(x, NaN) = NaN
+// Nextafter(NaN, y) = NaN
+// Nextafter(x, NaN) = NaN
func Nextafter(x, y float64) (r float64) {
// TODO(rsc): Remove manual inlining of IsNaN
// when compiler does it for us
@@ -25,5 +25,5 @@ func Nextafter(x, y float64) (r float64) {
default:
r = Float64frombits(Float64bits(x) - 1)
}
- return r
+ return
}
diff --git a/libgo/go/math/pow10.go b/libgo/go/math/pow10.go
index 20f91bcb70c..f5ad28bb4b0 100644
--- a/libgo/go/math/pow10.go
+++ b/libgo/go/math/pow10.go
@@ -9,6 +9,10 @@ package math
var pow10tab [70]float64
// Pow10 returns 10**e, the base-10 exponential of e.
+//
+// Special cases are:
+// Pow10(e) = +Inf for e > 309
+// Pow10(e) = 0 for e < -324
func Pow10(e int) float64 {
if e <= -325 {
return 0
diff --git a/libgo/go/math/remainder.go b/libgo/go/math/remainder.go
index 7fb8a12f9e6..77811b183f5 100644
--- a/libgo/go/math/remainder.go
+++ b/libgo/go/math/remainder.go
@@ -29,12 +29,16 @@ package math
// Remainder returns the IEEE 754 floating-point remainder of x/y.
//
// Special cases are:
-// Remainder(x, NaN) = NaN
+// Remainder(±Inf, y) = NaN
// Remainder(NaN, y) = NaN
-// Remainder(Inf, y) = NaN
// Remainder(x, 0) = NaN
-// Remainder(x, Inf) = x
+// Remainder(x, ±Inf) = x
+// Remainder(x, NaN) = NaN
func Remainder(x, y float64) float64 {
+ return remainder(x, y)
+}
+
+func remainder(x, y float64) float64 {
const (
Tiny = 4.45014771701440276618e-308 // 0x0020000000000000
HalfMax = MaxFloat64 / 2
diff --git a/libgo/go/math/sin.go b/libgo/go/math/sin.go
index b2a3f8a4e0e..2fbe3e7ec5b 100644
--- a/libgo/go/math/sin.go
+++ b/libgo/go/math/sin.go
@@ -113,7 +113,12 @@ var _cos = [...]float64{
// Special cases are:
// Cos(±Inf) = NaN
// Cos(NaN) = NaN
+func libc_cos(float64) float64 __asm__("cos")
func Cos(x float64) float64 {
+ return libc_cos(x)
+}
+
+func cos(x float64) float64 {
const (
PI4A = 7.85398125648498535156E-1 // 0x3fe921fb40000000, Pi/4 split into three parts
PI4B = 3.77489470793079817668E-8 // 0x3e64442d00000000,
@@ -166,11 +171,16 @@ func Cos(x float64) float64 {
// Sin returns the sine of x.
//
-// Special conditions are:
+// Special cases are:
// Sin(±0) = ±0
// Sin(±Inf) = NaN
// Sin(NaN) = NaN
+func libc_sin(float64) float64 __asm__("sin")
func Sin(x float64) float64 {
+ return libc_sin(x)
+}
+
+func sin(x float64) float64 {
const (
PI4A = 7.85398125648498535156E-1 // 0x3fe921fb40000000, Pi/4 split into three parts
PI4B = 3.77489470793079817668E-8 // 0x3e64442d00000000,
diff --git a/libgo/go/math/sincos.go b/libgo/go/math/sincos.go
index 74294256beb..f0de0893e19 100644
--- a/libgo/go/math/sincos.go
+++ b/libgo/go/math/sincos.go
@@ -13,6 +13,10 @@ package math
// Sincos(±Inf) = NaN, NaN
// Sincos(NaN) = NaN, NaN
func Sincos(x float64) (sin, cos float64) {
+ return sincos(x)
+}
+
+func sincos(x float64) (sin, cos float64) {
const (
PI4A = 7.85398125648498535156E-1 // 0x3fe921fb40000000, Pi/4 split into three parts
PI4B = 3.77489470793079817668E-8 // 0x3e64442d00000000,
diff --git a/libgo/go/math/sqrt.go b/libgo/go/math/sqrt.go
index bf6ef64a0b4..fb3aff8e4fc 100644
--- a/libgo/go/math/sqrt.go
+++ b/libgo/go/math/sqrt.go
@@ -4,7 +4,95 @@
package math
+// Sqrt returns the square root of x.
+//
+// Special cases are:
+// Sqrt(+Inf) = +Inf
+// Sqrt(±0) = ±0
+// Sqrt(x < 0) = NaN
+// Sqrt(NaN) = NaN
func libc_sqrt(float64) float64 __asm__("sqrt")
+func Sqrt(x float64) float64 {
+ return libc_sqrt(x)
+}
+
+// The original C code and the long comment below are
+// from FreeBSD's /usr/src/lib/msun/src/e_sqrt.c and
+// came with this notice. The go code is a simplified
+// version of the original C.
+//
+// ====================================================
+// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+//
+// Developed at SunPro, a Sun Microsystems, Inc. business.
+// Permission to use, copy, modify, and distribute this
+// software is freely granted, provided that this notice
+// is preserved.
+// ====================================================
+//
+// __ieee754_sqrt(x)
+// Return correctly rounded sqrt.
+// -----------------------------------------
+// | Use the hardware sqrt if you have one |
+// -----------------------------------------
+// Method:
+// Bit by bit method using integer arithmetic. (Slow, but portable)
+// 1. Normalization
+// Scale x to y in [1,4) with even powers of 2:
+// find an integer k such that 1 <= (y=x*2**(2k)) < 4, then
+// sqrt(x) = 2**k * sqrt(y)
+// 2. Bit by bit computation
+// Let q = sqrt(y) truncated to i bit after binary point (q = 1),
+// i 0
+// i+1 2
+// s = 2*q , and y = 2 * ( y - q ). (1)
+// i i i i
+//
+// To compute q from q , one checks whether
+// i+1 i
+//
+// -(i+1) 2
+// (q + 2 ) <= y. (2)
+// i
+// -(i+1)
+// If (2) is false, then q = q ; otherwise q = q + 2 .
+// i+1 i i+1 i
+//
+// With some algebraic manipulation, it is not difficult to see
+// that (2) is equivalent to
+// -(i+1)
+// s + 2 <= y (3)
+// i i
+//
+// The advantage of (3) is that s and y can be computed by
+// i i
+// the following recurrence formula:
+// if (3) is false
+//
+// s = s , y = y ; (4)
+// i+1 i i+1 i
+//
+// otherwise,
+// -i -(i+1)
+// s = s + 2 , y = y - s - 2 (5)
+// i+1 i i+1 i i
+//
+// One may easily use induction to prove (4) and (5).
+// Note. Since the left hand side of (3) contain only i+2 bits,
+// it does not necessary to do a full (53-bit) comparison
+// in (3).
+// 3. Final rounding
+// After generating the 53 bits result, we compute one more bit.
+// Together with the remainder, we can decide whether the
+// result is exact, bigger than 1/2ulp, or less than 1/2ulp
+// (it will never equal to 1/2ulp).
+// The rounding mode can be detected by checking whether
+// huge + tiny is equal to huge, and whether huge - tiny is
+// equal to huge for some floating point number "huge" and "tiny".
+//
+//
+// Notes: Rounding mode detection omitted. The constants "mask", "shift",
+// and "bias" are found in src/pkg/math/bits.go
// Sqrt returns the square root of x.
//
@@ -13,7 +101,7 @@ func libc_sqrt(float64) float64 __asm__("sqrt")
// Sqrt(±0) = ±0
// Sqrt(x < 0) = NaN
// Sqrt(NaN) = NaN
-func Sqrt(x float64) float64 {
+func sqrt(x float64) float64 {
// special cases
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
@@ -23,6 +111,45 @@ func Sqrt(x float64) float64 {
case x < 0:
return NaN()
}
+ ix := Float64bits(x)
+ // normalize x
+ exp := int((ix >> shift) & mask)
+ if exp == 0 { // subnormal x
+ for ix&1<<shift == 0 {
+ ix <<= 1
+ exp--
+ }
+ exp++
+ }
+ exp -= bias // unbias exponent
+ ix &^= mask << shift
+ ix |= 1 << shift
+ if exp&1 == 1 { // odd exp, double x to make it even
+ ix <<= 1
+ }
+ exp >>= 1 // exp = exp/2, exponent of square root
+ // generate sqrt(x) bit by bit
+ ix <<= 1
+ var q, s uint64 // q = sqrt(x)
+ r := uint64(1 << (shift + 1)) // r = moving bit from MSB to LSB
+ for r != 0 {
+ t := s + r
+ if t <= ix {
+ s = t + r
+ ix -= t
+ q += r
+ }
+ ix <<= 1
+ r >>= 1
+ }
+ // final rounding
+ if ix != 0 { // remainder, result not exact
+ q += q & 1 // round according to extra bit
+ }
+ ix = q>>1 + uint64(exp-1+bias)<<shift // significand + biased exponent
+ return Float64frombits(ix)
+}
- return libc_sqrt(x)
+func sqrtC(f float64, r *float64) {
+ *r = sqrt(f)
}
diff --git a/libgo/go/math/sqrt_decl.go b/libgo/go/math/sqrt_decl.go
deleted file mode 100644
index e507746458b..00000000000
--- a/libgo/go/math/sqrt_decl.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// 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
-
-func Sqrt(x float64) float64
diff --git a/libgo/go/math/sqrt_port.go b/libgo/go/math/sqrt_port.go
deleted file mode 100644
index 148239bcff6..00000000000
--- a/libgo/go/math/sqrt_port.go
+++ /dev/null
@@ -1,147 +0,0 @@
-// 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
-
-/*
- Floating-point square root.
-*/
-
-// The original C code and the long comment below are
-// from FreeBSD's /usr/src/lib/msun/src/e_sqrt.c and
-// came with this notice. The go code is a simplified
-// version of the original C.
-//
-// ====================================================
-// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-//
-// Developed at SunPro, a Sun Microsystems, Inc. business.
-// Permission to use, copy, modify, and distribute this
-// software is freely granted, provided that this notice
-// is preserved.
-// ====================================================
-//
-// __ieee754_sqrt(x)
-// Return correctly rounded sqrt.
-// -----------------------------------------
-// | Use the hardware sqrt if you have one |
-// -----------------------------------------
-// Method:
-// Bit by bit method using integer arithmetic. (Slow, but portable)
-// 1. Normalization
-// Scale x to y in [1,4) with even powers of 2:
-// find an integer k such that 1 <= (y=x*2**(2k)) < 4, then
-// sqrt(x) = 2**k * sqrt(y)
-// 2. Bit by bit computation
-// Let q = sqrt(y) truncated to i bit after binary point (q = 1),
-// i 0
-// i+1 2
-// s = 2*q , and y = 2 * ( y - q ). (1)
-// i i i i
-//
-// To compute q from q , one checks whether
-// i+1 i
-//
-// -(i+1) 2
-// (q + 2 ) <= y. (2)
-// i
-// -(i+1)
-// If (2) is false, then q = q ; otherwise q = q + 2 .
-// i+1 i i+1 i
-//
-// With some algebraic manipulation, it is not difficult to see
-// that (2) is equivalent to
-// -(i+1)
-// s + 2 <= y (3)
-// i i
-//
-// The advantage of (3) is that s and y can be computed by
-// i i
-// the following recurrence formula:
-// if (3) is false
-//
-// s = s , y = y ; (4)
-// i+1 i i+1 i
-//
-// otherwise,
-// -i -(i+1)
-// s = s + 2 , y = y - s - 2 (5)
-// i+1 i i+1 i i
-//
-// One may easily use induction to prove (4) and (5).
-// Note. Since the left hand side of (3) contain only i+2 bits,
-// it does not necessary to do a full (53-bit) comparison
-// in (3).
-// 3. Final rounding
-// After generating the 53 bits result, we compute one more bit.
-// Together with the remainder, we can decide whether the
-// result is exact, bigger than 1/2ulp, or less than 1/2ulp
-// (it will never equal to 1/2ulp).
-// The rounding mode can be detected by checking whether
-// huge + tiny is equal to huge, and whether huge - tiny is
-// equal to huge for some floating point number "huge" and "tiny".
-//
-//
-// Notes: Rounding mode detection omitted. The constants "mask", "shift",
-// and "bias" are found in src/pkg/math/bits.go
-
-// Sqrt returns the square root of x.
-//
-// Special cases are:
-// Sqrt(+Inf) = +Inf
-// Sqrt(±0) = ±0
-// Sqrt(x < 0) = NaN
-// Sqrt(NaN) = NaN
-func sqrtGo(x float64) float64 {
- // special cases
- // TODO(rsc): Remove manual inlining of IsNaN, IsInf
- // when compiler does it for us
- switch {
- case x == 0 || x != x || x > MaxFloat64: // x == 0 || IsNaN(x) || IsInf(x, 1):
- return x
- case x < 0:
- return NaN()
- }
- ix := Float64bits(x)
- // normalize x
- exp := int((ix >> shift) & mask)
- if exp == 0 { // subnormal x
- for ix&1<<shift == 0 {
- ix <<= 1
- exp--
- }
- exp++
- }
- exp -= bias // unbias exponent
- ix &^= mask << shift
- ix |= 1 << shift
- if exp&1 == 1 { // odd exp, double x to make it even
- ix <<= 1
- }
- exp >>= 1 // exp = exp/2, exponent of square root
- // generate sqrt(x) bit by bit
- ix <<= 1
- var q, s uint64 // q = sqrt(x)
- r := uint64(1 << (shift + 1)) // r = moving bit from MSB to LSB
- for r != 0 {
- t := s + r
- if t <= ix {
- s = t + r
- ix -= t
- q += r
- }
- ix <<= 1
- r >>= 1
- }
- // final rounding
- if ix != 0 { // remainder, result not exact
- q += q & 1 // round according to extra bit
- }
- ix = q>>1 + uint64(exp-1+bias)<<shift // significand + biased exponent
- return Float64frombits(ix)
-}
-
-func sqrtGoC(f float64, r *float64) {
- *r = sqrtGo(f)
-}
diff --git a/libgo/go/math/sqrt_test.go b/libgo/go/math/sqrt_test.go
deleted file mode 100644
index 84cbc169e81..00000000000
--- a/libgo/go/math/sqrt_test.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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 sqrtGo available for testing.
-
-func SqrtGo(x float64) float64 { return sqrtGo(x) }
diff --git a/libgo/go/math/tan.go b/libgo/go/math/tan.go
index 76131fcd935..926bb4b227e 100644
--- a/libgo/go/math/tan.go
+++ b/libgo/go/math/tan.go
@@ -79,7 +79,12 @@ var _tanQ = [...]float64{
// Tan(±0) = ±0
// Tan(±Inf) = NaN
// Tan(NaN) = NaN
+func libc_tan(float64) float64 __asm__("tan")
func Tan(x float64) float64 {
+ return libc_tan(x)
+}
+
+func tan(x float64) float64 {
const (
PI4A = 7.85398125648498535156E-1 // 0x3fe921fb40000000, Pi/4 split into three parts
PI4B = 3.77489470793079817668E-8 // 0x3e64442d00000000,