aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/math
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2018-09-24 21:46:21 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-09-24 21:46:21 +0000
commitdd931d9b48647e898dc80927c532ae93cc09e192 (patch)
tree71be2295cd79b8a182f6130611658db8628772d5 /libgo/go/math
parent779d8a5ad09b01428726ea5a0e6c87bd9ac3c0e4 (diff)
downloadgcc-dd931d9b48647e898dc80927c532ae93cc09e192.zip
gcc-dd931d9b48647e898dc80927c532ae93cc09e192.tar.gz
gcc-dd931d9b48647e898dc80927c532ae93cc09e192.tar.bz2
libgo: update to Go 1.11
Reviewed-on: https://go-review.googlesource.com/136435 gotools/: * Makefile.am (mostlyclean-local): Run chmod on check-go-dir to make sure it is writable. (check-go-tools): Likewise. (check-vet): Copy internal/objabi to check-vet-dir. * Makefile.in: Rebuild. From-SVN: r264546
Diffstat (limited to 'libgo/go/math')
-rw-r--r--libgo/go/math/all_test.go36
-rw-r--r--libgo/go/math/big/accuracy_string.go8
-rw-r--r--libgo/go/math/big/arith_amd64.go12
-rw-r--r--libgo/go/math/big/arith_test.go34
-rw-r--r--libgo/go/math/big/calibrate_test.go65
-rw-r--r--libgo/go/math/big/float.go10
-rw-r--r--libgo/go/math/big/float_test.go39
-rw-r--r--libgo/go/math/big/floatconv_test.go4
-rw-r--r--libgo/go/math/big/int.go371
-rw-r--r--libgo/go/math/big/int_test.go113
-rw-r--r--libgo/go/math/big/nat.go168
-rw-r--r--libgo/go/math/big/nat_test.go61
-rw-r--r--libgo/go/math/big/prime.go4
-rw-r--r--libgo/go/math/big/prime_test.go4
-rw-r--r--libgo/go/math/big/rat.go2
-rw-r--r--libgo/go/math/big/ratconv_test.go4
-rw-r--r--libgo/go/math/big/roundingmode_string.go8
-rw-r--r--libgo/go/math/big/sqrt.go20
-rw-r--r--libgo/go/math/bits/bits_test.go7
-rw-r--r--libgo/go/math/bits/export_test.go7
-rw-r--r--libgo/go/math/cmplx/cmath_test.go2
-rw-r--r--libgo/go/math/erfinv.go2
-rw-r--r--libgo/go/math/example_test.go24
-rw-r--r--libgo/go/math/floor_asm.go12
-rw-r--r--libgo/go/math/hypot.go7
-rw-r--r--libgo/go/math/j0.go4
-rw-r--r--libgo/go/math/ldexp.go6
-rw-r--r--libgo/go/math/lgamma.go2
-rw-r--r--libgo/go/math/rand/exp.go2
-rw-r--r--libgo/go/math/rand/normal.go6
-rw-r--r--libgo/go/math/rand/rand.go3
-rw-r--r--libgo/go/math/rand/regress_test.go508
-rw-r--r--libgo/go/math/rand/rng.go53
-rw-r--r--libgo/go/math/sin.go4
-rw-r--r--libgo/go/math/sinh.go14
35 files changed, 1039 insertions, 587 deletions
diff --git a/libgo/go/math/all_test.go b/libgo/go/math/all_test.go
index 98437b0..00f2058 100644
--- a/libgo/go/math/all_test.go
+++ b/libgo/go/math/all_test.go
@@ -25,7 +25,7 @@ var vf = []float64{
}
// The expected results below were computed by the high precision calculators
-// at http://keisan.casio.com/. More exact input values (array vf[], above)
+// at https://keisan.casio.com/. More exact input values (array vf[], above)
// were obtained by printing them with "%.26f". The answers were calculated
// to 26 digits (by using the "Digit number" drop-down control of each
// calculator).
@@ -946,6 +946,8 @@ var vferfSC = []float64{
0,
Inf(1),
NaN(),
+ -1000,
+ 1000,
}
var erfSC = []float64{
-1,
@@ -953,17 +955,23 @@ var erfSC = []float64{
0,
1,
NaN(),
+ -1,
+ 1,
}
var vferfcSC = []float64{
Inf(-1),
Inf(1),
NaN(),
+ -1000,
+ 1000,
}
var erfcSC = []float64{
2,
0,
NaN(),
+ 2,
+ 0,
}
var vferfinvSC = []float64{
@@ -1012,6 +1020,10 @@ var vfexpSC = []float64{
1.48852223e+09,
1.4885222e+09,
1,
+ // near zero
+ 3.725290298461915e-09,
+ // denormal
+ -740,
}
var expSC = []float64{
0,
@@ -1023,6 +1035,8 @@ var expSC = []float64{
Inf(1),
Inf(1),
2.718281828459045,
+ 1.0000000037252903,
+ 4.2e-322,
}
var vfexp2SC = []float64{
@@ -1033,6 +1047,10 @@ var vfexp2SC = []float64{
NaN(),
// smallest float64 that overflows Exp2(x)
1024,
+ // near underflow
+ -1.07399999999999e+03,
+ // near zero
+ 3.725290298461915e-09,
}
var exp2SC = []float64{
0,
@@ -1041,6 +1059,8 @@ var exp2SC = []float64{
Inf(1),
NaN(),
Inf(1),
+ 5e-324,
+ 1.0000000025821745,
}
var vfexpm1SC = []float64{
@@ -1955,6 +1975,8 @@ var vfldexpBC = []fi{
{-1, -1075},
{1, 1024},
{-1, 1024},
+ {1.0000000000000002, -1075},
+ {1, -1075},
}
var ldexpBC = []float64{
SmallestNonzeroFloat64,
@@ -1965,6 +1987,8 @@ var ldexpBC = []float64{
Copysign(0, -1),
Inf(1),
Inf(-1),
+ SmallestNonzeroFloat64,
+ 0,
}
var logbBC = []float64{
@@ -2316,7 +2340,7 @@ func testExp2(t *testing.T, Exp2 func(float64) float64, name string) {
}
for i := 0; i < len(vfexp2SC); i++ {
if f := Exp2(vfexp2SC[i]); !alike(exp2SC[i], f) {
- t.Errorf("%s(%g) = %g, want %g", name, vfexpSC[i], f, expSC[i])
+ t.Errorf("%s(%g) = %g, want %g", name, vfexp2SC[i], f, exp2SC[i])
}
}
for n := -1074; n < 1024; n++ {
@@ -2419,6 +2443,10 @@ func TestMod(t *testing.T) {
t.Errorf("Mod(%g, %g) = %g, want %g", vffmodSC[i][0], vffmodSC[i][1], f, fmodSC[i])
}
}
+ // verify precision of result for extreme inputs
+ if f := Mod(5.9790119248836734e+200, 1.1258465975523544); 0.6447968302508578 != f {
+ t.Errorf("Remainder(5.9790119248836734e+200, 1.1258465975523544) = %g, want 0.6447968302508578", f)
+ }
}
func TestFrexp(t *testing.T) {
@@ -2760,6 +2788,10 @@ func TestRemainder(t *testing.T) {
t.Errorf("Remainder(%g, %g) = %g, want %g", vffmodSC[i][0], vffmodSC[i][1], f, fmodSC[i])
}
}
+ // verify precision of result for extreme inputs
+ if f := Remainder(5.9790119248836734e+200, 1.1258465975523544); -0.4810497673014966 != f {
+ t.Errorf("Remainder(5.9790119248836734e+200, 1.1258465975523544) = %g, want -0.4810497673014966", f)
+ }
}
func TestRound(t *testing.T) {
diff --git a/libgo/go/math/big/accuracy_string.go b/libgo/go/math/big/accuracy_string.go
index 24ef7f1..1501ace 100644
--- a/libgo/go/math/big/accuracy_string.go
+++ b/libgo/go/math/big/accuracy_string.go
@@ -1,8 +1,8 @@
-// generated by stringer -type=Accuracy; DO NOT EDIT
+// Code generated by "stringer -type=Accuracy"; DO NOT EDIT.
package big
-import "fmt"
+import "strconv"
const _Accuracy_name = "BelowExactAbove"
@@ -10,8 +10,8 @@ var _Accuracy_index = [...]uint8{0, 5, 10, 15}
func (i Accuracy) String() string {
i -= -1
- if i < 0 || i+1 >= Accuracy(len(_Accuracy_index)) {
- return fmt.Sprintf("Accuracy(%d)", i+-1)
+ if i < 0 || i >= Accuracy(len(_Accuracy_index)-1) {
+ return "Accuracy(" + strconv.FormatInt(int64(i+-1), 10) + ")"
}
return _Accuracy_name[_Accuracy_index[i]:_Accuracy_index[i+1]]
}
diff --git a/libgo/go/math/big/arith_amd64.go b/libgo/go/math/big/arith_amd64.go
new file mode 100644
index 0000000..35164f3
--- /dev/null
+++ b/libgo/go/math/big/arith_amd64.go
@@ -0,0 +1,12 @@
+// Copyright 2017 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.
+
+// +build ignore_for_gccgo
+// +build !math_big_pure_go
+
+package big
+
+import "internal/cpu"
+
+var support_adx = cpu.X86.HasADX && cpu.X86.HasBMI2
diff --git a/libgo/go/math/big/arith_test.go b/libgo/go/math/big/arith_test.go
index 13b0436..cf386b3 100644
--- a/libgo/go/math/big/arith_test.go
+++ b/libgo/go/math/big/arith_test.go
@@ -142,6 +142,23 @@ func BenchmarkAddVV(b *testing.B) {
}
}
+func BenchmarkSubVV(b *testing.B) {
+ for _, n := range benchSizes {
+ if isRaceBuilder && n > 1e3 {
+ continue
+ }
+ x := rndV(n)
+ y := rndV(n)
+ z := make([]Word, n)
+ b.Run(fmt.Sprint(n), func(b *testing.B) {
+ b.SetBytes(int64(n * _W))
+ for i := 0; i < b.N; i++ {
+ subVV(z, x, y)
+ }
+ })
+ }
+}
+
type funVW func(z, x []Word, y Word) (c Word)
type argVW struct {
z, x nat
@@ -255,6 +272,23 @@ func BenchmarkAddVW(b *testing.B) {
}
}
+func BenchmarkSubVW(b *testing.B) {
+ for _, n := range benchSizes {
+ if isRaceBuilder && n > 1e3 {
+ continue
+ }
+ x := rndV(n)
+ y := rndW()
+ z := make([]Word, n)
+ b.Run(fmt.Sprint(n), func(b *testing.B) {
+ b.SetBytes(int64(n * _S))
+ for i := 0; i < b.N; i++ {
+ subVW(z, x, y)
+ }
+ })
+ }
+}
+
type funVWW func(z, x []Word, y, r Word) (c Word)
type argVWW struct {
z, x nat
diff --git a/libgo/go/math/big/calibrate_test.go b/libgo/go/math/big/calibrate_test.go
index 2b96e74..4fa663f 100644
--- a/libgo/go/math/big/calibrate_test.go
+++ b/libgo/go/math/big/calibrate_test.go
@@ -28,24 +28,32 @@ import (
var calibrate = flag.Bool("calibrate", false, "run calibration test")
+const (
+ sqrModeMul = "mul(x, x)"
+ sqrModeBasic = "basicSqr(x)"
+ sqrModeKaratsuba = "karatsubaSqr(x)"
+)
+
func TestCalibrate(t *testing.T) {
- if *calibrate {
- computeKaratsubaThresholds()
-
- // compute basicSqrThreshold where overhead becomes negligible
- minSqr := computeSqrThreshold(10, 30, 1, 3)
- // compute karatsubaSqrThreshold where karatsuba is faster
- maxSqr := computeSqrThreshold(300, 500, 10, 3)
- if minSqr != 0 {
- fmt.Printf("found basicSqrThreshold = %d\n", minSqr)
- } else {
- fmt.Println("no basicSqrThreshold found")
- }
- if maxSqr != 0 {
- fmt.Printf("found karatsubaSqrThreshold = %d\n", maxSqr)
- } else {
- fmt.Println("no karatsubaSqrThreshold found")
- }
+ if !*calibrate {
+ return
+ }
+
+ computeKaratsubaThresholds()
+
+ // compute basicSqrThreshold where overhead becomes negligible
+ minSqr := computeSqrThreshold(10, 30, 1, 3, sqrModeMul, sqrModeBasic)
+ // compute karatsubaSqrThreshold where karatsuba is faster
+ maxSqr := computeSqrThreshold(200, 500, 10, 3, sqrModeBasic, sqrModeKaratsuba)
+ if minSqr != 0 {
+ fmt.Printf("found basicSqrThreshold = %d\n", minSqr)
+ } else {
+ fmt.Println("no basicSqrThreshold found")
+ }
+ if maxSqr != 0 {
+ fmt.Printf("found karatsubaSqrThreshold = %d\n", maxSqr)
+ } else {
+ fmt.Println("no karatsubaSqrThreshold found")
}
}
@@ -109,16 +117,17 @@ func computeKaratsubaThresholds() {
}
}
-func measureBasicSqr(words, nruns int, enable bool) time.Duration {
+func measureSqr(words, nruns int, mode string) time.Duration {
// more runs for better statistics
initBasicSqr, initKaratsubaSqr := basicSqrThreshold, karatsubaSqrThreshold
- if enable {
- // set thresholds to use basicSqr at this number of words
+ switch mode {
+ case sqrModeMul:
+ basicSqrThreshold = words + 1
+ case sqrModeBasic:
basicSqrThreshold, karatsubaSqrThreshold = words-1, words+1
- } else {
- // set thresholds to disable basicSqr for any number of words
- basicSqrThreshold, karatsubaSqrThreshold = -1, -1
+ case sqrModeKaratsuba:
+ karatsubaSqrThreshold = words - 1
}
var testval int64
@@ -133,18 +142,18 @@ func measureBasicSqr(words, nruns int, enable bool) time.Duration {
return time.Duration(testval)
}
-func computeSqrThreshold(from, to, step, nruns int) int {
- fmt.Println("Calibrating thresholds for basicSqr via benchmarks of z.mul(x,x)")
+func computeSqrThreshold(from, to, step, nruns int, lower, upper string) int {
+ fmt.Printf("Calibrating threshold between %s and %s\n", lower, upper)
fmt.Printf("Looking for a timing difference for x between %d - %d words by %d step\n", from, to, step)
var initPos bool
var threshold int
for i := from; i <= to; i += step {
- baseline := measureBasicSqr(i, nruns, false)
- testval := measureBasicSqr(i, nruns, true)
+ baseline := measureSqr(i, nruns, lower)
+ testval := measureSqr(i, nruns, upper)
pos := baseline > testval
delta := baseline - testval
percent := delta * 100 / baseline
- fmt.Printf("words = %3d deltaT = %10s (%4d%%) is basicSqr better: %v", i, delta, percent, pos)
+ fmt.Printf("words = %3d deltaT = %10s (%4d%%) is %s better: %v", i, delta, percent, upper, pos)
if i == from {
initPos = pos
}
diff --git a/libgo/go/math/big/float.go b/libgo/go/math/big/float.go
index c042854..55b93c8 100644
--- a/libgo/go/math/big/float.go
+++ b/libgo/go/math/big/float.go
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// This file implements multi-precision floating-point numbers.
-// Like in the GNU MPFR library (http://www.mpfr.org/), operands
+// Like in the GNU MPFR library (https://www.mpfr.org/), operands
// can be of mixed precision. Unlike MPFR, the rounding mode is
// not specified with each operation, but with each operand. The
// rounding mode of the result operand determines the rounding
@@ -1429,8 +1429,6 @@ func (x *Float) ucmp(y *Float) int {
// z's accuracy reports the result error relative to the exact (not rounded)
// result. Add panics with ErrNaN if x and y are infinities with opposite
// signs. The value of z is undefined in that case.
-//
-// BUG(gri) When rounding ToNegativeInf, the sign of Float values rounded to 0 is incorrect.
func (z *Float) Add(x, y *Float) *Float {
if debugFloat {
x.validate()
@@ -1466,6 +1464,9 @@ func (z *Float) Add(x, y *Float) *Float {
z.usub(y, x)
}
}
+ if z.form == zero && z.mode == ToNegativeInf && z.acc == Exact {
+ z.neg = true
+ }
return z
}
@@ -1530,6 +1531,9 @@ func (z *Float) Sub(x, y *Float) *Float {
z.usub(y, x)
}
}
+ if z.form == zero && z.mode == ToNegativeInf && z.acc == Exact {
+ z.neg = true
+ }
return z
}
diff --git a/libgo/go/math/big/float_test.go b/libgo/go/math/big/float_test.go
index 5fd49bb..7d6bf03 100644
--- a/libgo/go/math/big/float_test.go
+++ b/libgo/go/math/big/float_test.go
@@ -1007,9 +1007,9 @@ func TestFloatFloat64(t *testing.T) {
{"0x.fffffffffffffp-1022", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact},
{"4503599627370495p-1074", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact},
- // http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
+ // https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
{"2.2250738585072011e-308", 2.225073858507201e-308, Below},
- // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
+ // https://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
{"2.2250738585072012e-308", 2.2250738585072014e-308, Above},
} {
for i := 0; i < 2; i++ {
@@ -1258,6 +1258,31 @@ func TestFloatAdd(t *testing.T) {
}
}
+// TestFloatAddRoundZero tests Float.Add/Sub rounding when the result is exactly zero.
+// x + (-x) or x - x for non-zero x should be +0 in all cases except when
+// the rounding mode is ToNegativeInf in which case it should be -0.
+func TestFloatAddRoundZero(t *testing.T) {
+ for _, mode := range [...]RoundingMode{ToNearestEven, ToNearestAway, ToZero, AwayFromZero, ToPositiveInf, ToNegativeInf} {
+ x := NewFloat(5.0)
+ y := new(Float).Neg(x)
+ want := NewFloat(0.0)
+ if mode == ToNegativeInf {
+ want.Neg(want)
+ }
+ got := new(Float).SetMode(mode)
+ got.Add(x, y)
+ if got.Cmp(want) != 0 || got.neg != (mode == ToNegativeInf) {
+ t.Errorf("%s:\n\t %v\n\t+ %v\n\t= %v\n\twant %v",
+ mode, x, y, got, want)
+ }
+ got.Sub(x, x)
+ if got.Cmp(want) != 0 || got.neg != (mode == ToNegativeInf) {
+ t.Errorf("%v:\n\t %v\n\t- %v\n\t= %v\n\twant %v",
+ mode, x, x, got, want)
+ }
+ }
+}
+
// TestFloatAdd32 tests that Float.Add/Sub of numbers with
// 24bit mantissa behaves like float32 addition/subtraction
// (excluding denormal numbers).
@@ -1372,7 +1397,7 @@ func TestFloatMul(t *testing.T) {
got.Mul(x, y)
want := zbits.round(prec, mode)
if got.Cmp(want) != 0 {
- t.Errorf("i = %d, prec = %d, %s:\n\t %s %v\n\t* %s %v\n\t= %s\n\twant %s",
+ t.Errorf("i = %d, prec = %d, %s:\n\t %v %v\n\t* %v %v\n\t= %v\n\twant %v",
i, prec, mode, x, xbits, y, ybits, got, want)
}
@@ -1382,7 +1407,7 @@ func TestFloatMul(t *testing.T) {
got.Quo(z, x)
want = ybits.round(prec, mode)
if got.Cmp(want) != 0 {
- t.Errorf("i = %d, prec = %d, %s:\n\t %s %v\n\t/ %s %v\n\t= %s\n\twant %s",
+ t.Errorf("i = %d, prec = %d, %s:\n\t %v %v\n\t/ %v %v\n\t= %v\n\twant %v",
i, prec, mode, z, zbits, x, xbits, got, want)
}
}
@@ -1465,13 +1490,13 @@ func TestIssue6866(t *testing.T) {
z2.Sub(two, p)
if z1.Cmp(z2) != 0 {
- t.Fatalf("prec %d: got z1 = %s != z2 = %s; want z1 == z2\n", prec, z1, z2)
+ t.Fatalf("prec %d: got z1 = %v != z2 = %v; want z1 == z2\n", prec, z1, z2)
}
if z1.Sign() != 0 {
- t.Errorf("prec %d: got z1 = %s; want 0", prec, z1)
+ t.Errorf("prec %d: got z1 = %v; want 0", prec, z1)
}
if z2.Sign() != 0 {
- t.Errorf("prec %d: got z2 = %s; want 0", prec, z2)
+ t.Errorf("prec %d: got z2 = %v; want 0", prec, z2)
}
}
}
diff --git a/libgo/go/math/big/floatconv_test.go b/libgo/go/math/big/floatconv_test.go
index 6d0f17d..269e265 100644
--- a/libgo/go/math/big/floatconv_test.go
+++ b/libgo/go/math/big/floatconv_test.go
@@ -286,9 +286,9 @@ func TestFloat64Text(t *testing.T) {
{0.5, 'f', 0, "0"},
{1.5, 'f', 0, "2"},
- // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
+ // https://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
{2.2250738585072012e-308, 'g', -1, "2.2250738585072014e-308"},
- // http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
+ // https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
{2.2250738585072011e-308, 'g', -1, "2.225073858507201e-308"},
// Issue 2625.
diff --git a/libgo/go/math/big/int.go b/libgo/go/math/big/int.go
index 0eda9cd..47a288a 100644
--- a/libgo/go/math/big/int.go
+++ b/libgo/go/math/big/int.go
@@ -442,24 +442,28 @@ func (x *Int) BitLen() int {
}
// Exp sets z = x**y mod |m| (i.e. the sign of m is ignored), and returns z.
-// If y <= 0, the result is 1 mod |m|; if m == nil or m == 0, z = x**y.
+// If m == nil or m == 0, z = x**y unless y <= 0 then z = 1.
//
// Modular exponentation of inputs of a particular size is not a
// cryptographically constant-time operation.
func (z *Int) Exp(x, y, m *Int) *Int {
// See Knuth, volume 2, section 4.6.3.
- var yWords nat
- if !y.neg {
- yWords = y.abs
+ xWords := x.abs
+ if y.neg {
+ if m == nil || len(m.abs) == 0 {
+ return z.SetInt64(1)
+ }
+ // for y < 0: x**y mod m == (x**(-1))**|y| mod m
+ xWords = new(Int).ModInverse(x, m).abs
}
- // y >= 0
+ yWords := y.abs
var mWords nat
if m != nil {
mWords = m.abs // m.abs may be nil for m == 0
}
- z.abs = z.abs.expNN(x.abs, yWords, mWords)
+ z.abs = z.abs.expNN(xWords, yWords, mWords)
z.neg = len(z.abs) > 0 && x.neg && len(yWords) > 0 && yWords[0]&1 == 1 // 0 has no sign
if z.neg && len(mWords) > 0 {
// make modulus result positive
@@ -485,162 +489,223 @@ func (z *Int) GCD(x, y, a, b *Int) *Int {
}
return z
}
- if x == nil && y == nil {
- return z.lehmerGCD(a, b)
- }
- A := new(Int).Set(a)
- B := new(Int).Set(b)
-
- X := new(Int)
- lastX := new(Int).SetInt64(1)
+ return z.lehmerGCD(x, y, a, b)
+}
- q := new(Int)
- temp := new(Int)
+// lehmerSimulate attempts to simulate several Euclidean update steps
+// using the leading digits of A and B. It returns u0, u1, v0, v1
+// such that A and B can be updated as:
+// A = u0*A + v0*B
+// B = u1*A + v1*B
+// Requirements: A >= B and len(B.abs) >= 2
+// Since we are calculating with full words to avoid overflow,
+// we use 'even' to track the sign of the cosequences.
+// For even iterations: u0, v1 >= 0 && u1, v0 <= 0
+// For odd iterations: u0, v1 <= 0 && u1, v0 >= 0
+func lehmerSimulate(A, B *Int) (u0, u1, v0, v1 Word, even bool) {
+ // initialize the digits
+ var a1, a2, u2, v2 Word
+
+ m := len(B.abs) // m >= 2
+ n := len(A.abs) // n >= m >= 2
+
+ // extract the top Word of bits from A and B
+ h := nlz(A.abs[n-1])
+ a1 = A.abs[n-1]<<h | A.abs[n-2]>>(_W-h)
+ // B may have implicit zero words in the high bits if the lengths differ
+ switch {
+ case n == m:
+ a2 = B.abs[n-1]<<h | B.abs[n-2]>>(_W-h)
+ case n == m+1:
+ a2 = B.abs[n-2] >> (_W - h)
+ default:
+ a2 = 0
+ }
- r := new(Int)
- for len(B.abs) > 0 {
- q, r = q.QuoRem(A, B, r)
+ // Since we are calculating with full words to avoid overflow,
+ // we use 'even' to track the sign of the cosequences.
+ // For even iterations: u0, v1 >= 0 && u1, v0 <= 0
+ // For odd iterations: u0, v1 <= 0 && u1, v0 >= 0
+ // The first iteration starts with k=1 (odd).
+ even = false
+ // variables to track the cosequences
+ u0, u1, u2 = 0, 1, 0
+ v0, v1, v2 = 0, 0, 1
+
+ // Calculate the quotient and cosequences using Collins' stopping condition.
+ // Note that overflow of a Word is not possible when computing the remainder
+ // sequence and cosequences since the cosequence size is bounded by the input size.
+ // See section 4.2 of Jebelean for details.
+ for a2 >= v2 && a1-a2 >= v1+v2 {
+ q, r := a1/a2, a1%a2
+ a1, a2 = a2, r
+ u0, u1, u2 = u1, u2, u1+q*u2
+ v0, v1, v2 = v1, v2, v1+q*v2
+ even = !even
+ }
+ return
+}
- A, B, r = B, r, A
+// lehmerUpdate updates the inputs A and B such that:
+// A = u0*A + v0*B
+// B = u1*A + v1*B
+// where the signs of u0, u1, v0, v1 are given by even
+// For even == true: u0, v1 >= 0 && u1, v0 <= 0
+// For even == false: u0, v1 <= 0 && u1, v0 >= 0
+// q, r, s, t are temporary variables to avoid allocations in the multiplication
+func lehmerUpdate(A, B, q, r, s, t *Int, u0, u1, v0, v1 Word, even bool) {
+
+ t.abs = t.abs.setWord(u0)
+ s.abs = s.abs.setWord(v0)
+ t.neg = !even
+ s.neg = even
+
+ t.Mul(A, t)
+ s.Mul(B, s)
+
+ r.abs = r.abs.setWord(u1)
+ q.abs = q.abs.setWord(v1)
+ r.neg = even
+ q.neg = !even
+
+ r.Mul(A, r)
+ q.Mul(B, q)
+
+ A.Add(t, s)
+ B.Add(r, q)
+}
- temp.Set(X)
- X.Mul(X, q)
- X.Sub(lastX, X)
- lastX.Set(temp)
- }
+// euclidUpdate performs a single step of the Euclidean GCD algorithm
+// if extended is true, it also updates the cosequence Ua, Ub
+func euclidUpdate(A, B, Ua, Ub, q, r, s, t *Int, extended bool) {
+ q, r = q.QuoRem(A, B, r)
- if x != nil {
- *x = *lastX
- }
+ *A, *B, *r = *B, *r, *A
- if y != nil {
- // y = (z - a*x)/b
- y.Mul(a, lastX)
- y.Sub(A, y)
- y.Div(y, b)
+ if extended {
+ // Ua, Ub = Ub, Ua - q*Ub
+ t.Set(Ub)
+ s.Mul(Ub, q)
+ Ub.Sub(Ua, s)
+ Ua.Set(t)
}
-
- *z = *A
- return z
}
// lehmerGCD sets z to the greatest common divisor of a and b,
// which both must be > 0, and returns z.
+// If x or y are not nil, their values are set such that z = a*x + b*y.
// See Knuth, The Art of Computer Programming, Vol. 2, Section 4.5.2, Algorithm L.
// This implementation uses the improved condition by Collins requiring only one
// quotient and avoiding the possibility of single Word overflow.
// See Jebelean, "Improving the multiprecision Euclidean algorithm",
// Design and Implementation of Symbolic Computation Systems, pp 45-58.
-func (z *Int) lehmerGCD(a, b *Int) *Int {
- // ensure a >= b
- if a.abs.cmp(b.abs) < 0 {
- a, b = b, a
- }
+// The cosequences are updated according to Algorithm 10.45 from
+// Cohen et al. "Handbook of Elliptic and Hyperelliptic Curve Cryptography" pp 192.
+func (z *Int) lehmerGCD(x, y, a, b *Int) *Int {
+ var A, B, Ua, Ub *Int
- // don't destroy incoming values of a and b
- B := new(Int).Set(b) // must be set first in case b is an alias of z
- A := z.Set(a)
+ A = new(Int).Set(a)
+ B = new(Int).Set(b)
+
+ extended := x != nil || y != nil
+
+ if extended {
+ // Ua (Ub) tracks how many times input a has been accumulated into A (B).
+ Ua = new(Int).SetInt64(1)
+ Ub = new(Int)
+ }
// temp variables for multiprecision update
- t := new(Int)
+ q := new(Int)
r := new(Int)
s := new(Int)
- w := new(Int)
+ t := new(Int)
+
+ // ensure A >= B
+ if A.abs.cmp(B.abs) < 0 {
+ A, B = B, A
+ Ub, Ua = Ua, Ub
+ }
// loop invariant A >= B
for len(B.abs) > 1 {
- // initialize the digits
- var a1, a2, u0, u1, u2, v0, v1, v2 Word
-
- m := len(B.abs) // m >= 2
- n := len(A.abs) // n >= m >= 2
-
- // extract the top Word of bits from A and B
- h := nlz(A.abs[n-1])
- a1 = (A.abs[n-1] << h) | (A.abs[n-2] >> (_W - h))
- // B may have implicit zero words in the high bits if the lengths differ
- switch {
- case n == m:
- a2 = (B.abs[n-1] << h) | (B.abs[n-2] >> (_W - h))
- case n == m+1:
- a2 = (B.abs[n-2] >> (_W - h))
- default:
- a2 = 0
- }
-
- // Since we are calculating with full words to avoid overflow,
- // we use 'even' to track the sign of the cosequences.
- // For even iterations: u0, v1 >= 0 && u1, v0 <= 0
- // For odd iterations: u0, v1 <= 0 && u1, v0 >= 0
- // The first iteration starts with k=1 (odd).
- even := false
- // variables to track the cosequences
- u0, u1, u2 = 0, 1, 0
- v0, v1, v2 = 0, 0, 1
-
- // Calculate the quotient and cosequences using Collins' stopping condition.
- // Note that overflow of a Word is not possible when computing the remainder
- // sequence and cosequences since the cosequence size is bounded by the input size.
- // See section 4.2 of Jebelean for details.
- for a2 >= v2 && a1-a2 >= v1+v2 {
- q := a1 / a2
- a1, a2 = a2, a1-q*a2
- u0, u1, u2 = u1, u2, u1+q*u2
- v0, v1, v2 = v1, v2, v1+q*v2
- even = !even
- }
+ // Attempt to calculate in single-precision using leading words of A and B.
+ u0, u1, v0, v1, even := lehmerSimulate(A, B)
- // multiprecision step
+ // multiprecision Step
if v0 != 0 {
- // simulate the effect of the single precision steps using the cosequences
+ // Simulate the effect of the single-precision steps using the cosequences.
// A = u0*A + v0*B
// B = u1*A + v1*B
+ lehmerUpdate(A, B, q, r, s, t, u0, u1, v0, v1, even)
- t.abs = t.abs.setWord(u0)
- s.abs = s.abs.setWord(v0)
- t.neg = !even
- s.neg = even
-
- t.Mul(A, t)
- s.Mul(B, s)
-
- r.abs = r.abs.setWord(u1)
- w.abs = w.abs.setWord(v1)
- r.neg = even
- w.neg = !even
-
- r.Mul(A, r)
- w.Mul(B, w)
-
- A.Add(t, s)
- B.Add(r, w)
+ if extended {
+ // Ua = u0*Ua + v0*Ub
+ // Ub = u1*Ua + v1*Ub
+ lehmerUpdate(Ua, Ub, q, r, s, t, u0, u1, v0, v1, even)
+ }
} else {
- // single-digit calculations failed to simluate any quotients
- // do a standard Euclidean step
- t.Rem(A, B)
- A, B, t = B, t, A
+ // Single-digit calculations failed to simulate any quotients.
+ // Do a standard Euclidean step.
+ euclidUpdate(A, B, Ua, Ub, q, r, s, t, extended)
}
}
if len(B.abs) > 0 {
- // standard Euclidean algorithm base case for B a single Word
+ // extended Euclidean algorithm base case if B is a single Word
if len(A.abs) > 1 {
- // A is longer than a single Word
- t.Rem(A, B)
- A, B, t = B, t, A
+ // A is longer than a single Word, so one update is needed.
+ euclidUpdate(A, B, Ua, Ub, q, r, s, t, extended)
}
if len(B.abs) > 0 {
- // A and B are both a single Word
- a1, a2 := A.abs[0], B.abs[0]
- for a2 != 0 {
- a1, a2 = a2, a1%a2
+ // A and B are both a single Word.
+ aWord, bWord := A.abs[0], B.abs[0]
+ if extended {
+ var ua, ub, va, vb Word
+ ua, ub = 1, 0
+ va, vb = 0, 1
+ even := true
+ for bWord != 0 {
+ q, r := aWord/bWord, aWord%bWord
+ aWord, bWord = bWord, r
+ ua, ub = ub, ua+q*ub
+ va, vb = vb, va+q*vb
+ even = !even
+ }
+
+ t.abs = t.abs.setWord(ua)
+ s.abs = s.abs.setWord(va)
+ t.neg = !even
+ s.neg = even
+
+ t.Mul(Ua, t)
+ s.Mul(Ub, s)
+
+ Ua.Add(t, s)
+ } else {
+ for bWord != 0 {
+ aWord, bWord = bWord, aWord%bWord
+ }
}
- A.abs[0] = a1
+ A.abs[0] = aWord
}
}
+
+ if x != nil {
+ *x = *Ua
+ }
+
+ if y != nil {
+ // y = (z - a*x)/b
+ y.Mul(a, Ua)
+ y.Sub(A, y)
+ y.Div(y, b)
+ }
+
*z = *A
+
return z
}
@@ -659,20 +724,33 @@ func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int {
}
// ModInverse sets z to the multiplicative inverse of g in the ring ℤ/nℤ
-// and returns z. If g and n are not relatively prime, the result is undefined.
+// and returns z. If g and n are not relatively prime, g has no multiplicative
+// inverse in the ring ℤ/nℤ. In this case, z is unchanged and the return value
+// is nil.
func (z *Int) ModInverse(g, n *Int) *Int {
+ // GCD expects parameters a and b to be > 0.
+ if n.neg {
+ var n2 Int
+ n = n2.Neg(n)
+ }
if g.neg {
- // GCD expects parameters a and b to be > 0.
var g2 Int
g = g2.Mod(g, n)
}
- var d Int
- d.GCD(z, nil, g, n)
- // x and y are such that g*x + n*y = d. Since g and n are
- // relatively prime, d = 1. Taking that modulo n results in
- // g*x = 1, therefore x is the inverse element.
- if z.neg {
- z.Add(z, n)
+ var d, x Int
+ d.GCD(&x, nil, g, n)
+
+ // if and only if d==1, g and n are relatively prime
+ if d.Cmp(intOne) != 0 {
+ return nil
+ }
+
+ // x and y are such that g*x + n*y = 1, therefore x is the inverse element,
+ // but it may be negative, so convert to the range 0 <= z < |n|
+ if x.neg {
+ z.Add(&x, n)
+ } else {
+ z.Set(&x)
}
return z
}
@@ -745,6 +823,30 @@ func (z *Int) modSqrt3Mod4Prime(x, p *Int) *Int {
return z
}
+// modSqrt5Mod8 uses Atkin's observation that 2 is not a square mod p
+// alpha == (2*a)^((p-5)/8) mod p
+// beta == 2*a*alpha^2 mod p is a square root of -1
+// b == a*alpha*(beta-1) mod p is a square root of a
+// to calculate the square root of any quadratic residue mod p quickly for 5
+// mod 8 primes.
+func (z *Int) modSqrt5Mod8Prime(x, p *Int) *Int {
+ // p == 5 mod 8 implies p = e*8 + 5
+ // e is the quotient and 5 the remainder on division by 8
+ e := new(Int).Rsh(p, 3) // e = (p - 5) / 8
+ tx := new(Int).Lsh(x, 1) // tx = 2*x
+ alpha := new(Int).Exp(tx, e, p)
+ beta := new(Int).Mul(alpha, alpha)
+ beta.Mod(beta, p)
+ beta.Mul(beta, tx)
+ beta.Mod(beta, p)
+ beta.Sub(beta, intOne)
+ beta.Mul(beta, x)
+ beta.Mod(beta, p)
+ beta.Mul(beta, alpha)
+ z.Mod(beta, p)
+ return z
+}
+
// modSqrtTonelliShanks uses the Tonelli-Shanks algorithm to find the square
// root of a quadratic residue modulo any prime.
func (z *Int) modSqrtTonelliShanks(x, p *Int) *Int {
@@ -811,12 +913,17 @@ func (z *Int) ModSqrt(x, p *Int) *Int {
x = new(Int).Mod(x, p)
}
- // Check whether p is 3 mod 4, and if so, use the faster algorithm.
- if len(p.abs) > 0 && p.abs[0]%4 == 3 {
+ switch {
+ case p.abs[0]%4 == 3:
+ // Check whether p is 3 mod 4, and if so, use the faster algorithm.
return z.modSqrt3Mod4Prime(x, p)
+ case p.abs[0]%8 == 5:
+ // Check whether p is 5 mod 8, use Atkin's algorithm.
+ return z.modSqrt5Mod8Prime(x, p)
+ default:
+ // Otherwise, use Tonelli-Shanks.
+ return z.modSqrtTonelliShanks(x, p)
}
- // Otherwise, use Tonelli-Shanks.
- return z.modSqrtTonelliShanks(x, p)
}
// Lsh sets z = x << n and returns z.
diff --git a/libgo/go/math/big/int_test.go b/libgo/go/math/big/int_test.go
index 270fec6..9930ed0 100644
--- a/libgo/go/math/big/int_test.go
+++ b/libgo/go/math/big/int_test.go
@@ -557,7 +557,7 @@ var expTests = []struct {
{"0x8000000000000000", "3", "6719", "5447"},
{"0x8000000000000000", "1000", "6719", "1603"},
{"0x8000000000000000", "1000000", "6719", "3199"},
- {"0x8000000000000000", "-1000000", "6719", "1"},
+ {"0x8000000000000000", "-1000000", "6719", "3663"}, // 3663 = ModInverse(3199, 6719) Issue #25865
{"0xffffffffffffffffffffffffffffffff", "0x12345678123456781234567812345678123456789", "0x01112222333344445555666677778889", "0x36168FA1DB3AAE6C8CE647E137F97A"},
@@ -675,21 +675,43 @@ func checkGcd(aBytes, bBytes []byte) bool {
return x.Cmp(d) == 0
}
-// euclidGCD is a reference implementation of Euclid's GCD
-// algorithm for testing against optimized algorithms.
+// euclidExtGCD is a reference implementation of Euclid's
+// extended GCD algorithm for testing against optimized algorithms.
// Requirements: a, b > 0
-func euclidGCD(a, b *Int) *Int {
-
+func euclidExtGCD(a, b *Int) (g, x, y *Int) {
A := new(Int).Set(a)
B := new(Int).Set(b)
- t := new(Int)
+ // A = Ua*a + Va*b
+ // B = Ub*a + Vb*b
+ Ua := new(Int).SetInt64(1)
+ Va := new(Int)
+
+ Ub := new(Int)
+ Vb := new(Int).SetInt64(1)
+
+ q := new(Int)
+ temp := new(Int)
+
+ r := new(Int)
for len(B.abs) > 0 {
- // A, B = B, A % B
- t.Rem(A, B)
- A, B, t = B, t, A
+ q, r = q.QuoRem(A, B, r)
+
+ A, B, r = B, r, A
+
+ // Ua, Ub = Ub, Ua-q*Ub
+ temp.Set(Ub)
+ Ub.Mul(Ub, q)
+ Ub.Sub(Ua, Ub)
+ Ua.Set(temp)
+
+ // Va, Vb = Vb, Va-q*Vb
+ temp.Set(Vb)
+ Vb.Mul(Vb, q)
+ Vb.Sub(Va, Vb)
+ Va.Set(temp)
}
- return A
+ return A, Ua, Va
}
func checkLehmerGcd(aBytes, bBytes []byte) bool {
@@ -700,12 +722,28 @@ func checkLehmerGcd(aBytes, bBytes []byte) bool {
return true // can only test positive arguments
}
- d := new(Int).lehmerGCD(a, b)
- d0 := euclidGCD(a, b)
+ d := new(Int).lehmerGCD(nil, nil, a, b)
+ d0, _, _ := euclidExtGCD(a, b)
return d.Cmp(d0) == 0
}
+func checkLehmerExtGcd(aBytes, bBytes []byte) bool {
+ a := new(Int).SetBytes(aBytes)
+ b := new(Int).SetBytes(bBytes)
+ x := new(Int)
+ y := new(Int)
+
+ if a.Sign() <= 0 || b.Sign() <= 0 {
+ return true // can only test positive arguments
+ }
+
+ d := new(Int).lehmerGCD(x, y, a, b)
+ d0, x0, y0 := euclidExtGCD(a, b)
+
+ return d.Cmp(d0) == 0 && x.Cmp(x0) == 0 && y.Cmp(y0) == 0
+}
+
var gcdTests = []struct {
d, x, y, a, b string
}{
@@ -785,6 +823,10 @@ func TestGcd(t *testing.T) {
if err := quick.Check(checkLehmerGcd, nil); err != nil {
t.Error(err)
}
+
+ if err := quick.Check(checkLehmerExtGcd, nil); err != nil {
+ t.Error(err)
+ }
}
type intShiftTest struct {
@@ -1318,7 +1360,7 @@ func BenchmarkModSqrt225_Tonelli(b *testing.B) {
}
}
-func BenchmarkModSqrt224_3Mod4(b *testing.B) {
+func BenchmarkModSqrt225_3Mod4(b *testing.B) {
p := tri(225)
x := new(Int).SetUint64(2)
for i := 0; i < b.N; i++ {
@@ -1327,27 +1369,25 @@ func BenchmarkModSqrt224_3Mod4(b *testing.B) {
}
}
-func BenchmarkModSqrt5430_Tonelli(b *testing.B) {
- if isRaceBuilder {
- b.Skip("skipping on race builder")
- }
- p := tri(5430)
- x := new(Int).SetUint64(2)
+func BenchmarkModSqrt231_Tonelli(b *testing.B) {
+ p := tri(231)
+ p.Sub(p, intOne)
+ p.Sub(p, intOne) // tri(231) - 2 is a prime == 5 mod 8
+ x := new(Int).SetUint64(7)
for i := 0; i < b.N; i++ {
- x.SetUint64(2)
+ x.SetUint64(7)
x.modSqrtTonelliShanks(x, p)
}
}
-func BenchmarkModSqrt5430_3Mod4(b *testing.B) {
- if isRaceBuilder {
- b.Skip("skipping on race builder")
- }
- p := tri(5430)
- x := new(Int).SetUint64(2)
+func BenchmarkModSqrt231_5Mod8(b *testing.B) {
+ p := tri(231)
+ p.Sub(p, intOne)
+ p.Sub(p, intOne) // tri(231) - 2 is a prime == 5 mod 8
+ x := new(Int).SetUint64(7)
for i := 0; i < b.N; i++ {
- x.SetUint64(2)
- x.modSqrt3Mod4Prime(x, p)
+ x.SetUint64(7)
+ x.modSqrt5Mod8Prime(x, p)
}
}
@@ -1409,19 +1449,21 @@ var modInverseTests = []struct {
{"1234567", "458948883992"},
{"239487239847", "2410312426921032588552076022197566074856950548502459942654116941958108831682612228890093858261341614673227141477904012196503648957050582631942730706805009223062734745341073406696246014589361659774041027169249453200378729434170325843778659198143763193776859869524088940195577346119843545301547043747207749969763750084308926339295559968882457872412993810129130294592999947926365264059284647209730384947211681434464714438488520940127459844288859336526896320919633919"},
{"-10", "13"}, // issue #16984
+ {"10", "-13"},
+ {"-17", "-13"},
}
func TestModInverse(t *testing.T) {
var element, modulus, gcd, inverse Int
one := NewInt(1)
- for i, test := range modInverseTests {
+ for _, test := range modInverseTests {
(&element).SetString(test.element, 10)
(&modulus).SetString(test.modulus, 10)
(&inverse).ModInverse(&element, &modulus)
(&inverse).Mul(&inverse, &element)
(&inverse).Mod(&inverse, &modulus)
if (&inverse).Cmp(one) != 0 {
- t.Errorf("#%d: failed (e·e^(-1)=%s)", i, &inverse)
+ t.Errorf("ModInverse(%d,%d)*%d%%%d=%d, not 1", &element, &modulus, &element, &modulus, &inverse)
}
}
// exhaustive test for small values
@@ -1443,6 +1485,17 @@ func TestModInverse(t *testing.T) {
}
}
+func BenchmarkModInverse(b *testing.B) {
+ p := new(Int).SetInt64(1) // Mersenne prime 2**1279 -1
+ p.abs = p.abs.shl(p.abs, 1279)
+ p.Sub(p, intOne)
+ x := new(Int).Sub(p, intOne)
+ z := new(Int)
+ for i := 0; i < b.N; i++ {
+ z.ModInverse(x, p)
+ }
+}
+
// testModSqrt is a helper for TestModSqrt,
// which checks that ModSqrt can compute a square-root of elt^2.
func testModSqrt(t *testing.T, elt, mod, sq, sqrt *Int) bool {
diff --git a/libgo/go/math/big/nat.go b/libgo/go/math/big/nat.go
index 3bb818f..a6f79ed 100644
--- a/libgo/go/math/big/nat.go
+++ b/libgo/go/math/big/nat.go
@@ -5,10 +5,16 @@
// This file implements unsigned multi-precision integers (natural
// numbers). They are the building blocks for the implementation
// of signed integers, rationals, and floating-point numbers.
+//
+// Caution: This implementation relies on the function "alias"
+// which assumes that (nat) slice capacities are never
+// changed (no 3-operand slice expressions). If that
+// changes, alias needs to be updated for correctness.
package big
import (
+ "encoding/binary"
"math/bits"
"math/rand"
"sync"
@@ -207,18 +213,17 @@ func (z nat) montgomery(x, y, m nat, k Word, n int) nat {
if len(x) != n || len(y) != n || len(m) != n {
panic("math/big: mismatched montgomery number lengths")
}
- z = z.make(n)
+ z = z.make(n * 2)
z.clear()
var c Word
for i := 0; i < n; i++ {
d := y[i]
- c2 := addMulVVW(z, x, d)
- t := z[0] * k
- c3 := addMulVVW(z, m, t)
- copy(z, z[1:])
+ c2 := addMulVVW(z[i:n+i], x, d)
+ t := z[i] * k
+ c3 := addMulVVW(z[i:n+i], m, t)
cx := c + c2
cy := cx + c3
- z[n-1] = cy
+ z[n+i] = cy
if cx < c2 || cy < c3 {
c = 1
} else {
@@ -226,9 +231,11 @@ func (z nat) montgomery(x, y, m nat, k Word, n int) nat {
}
}
if c != 0 {
- subVV(z, z, m)
+ subVV(z[:n], z[n:], m)
+ } else {
+ copy(z[:n], z[n:])
}
- return z
+ return z[:n]
}
// Fast version of z[0:n+n>>1].add(z[0:n+n>>1], x[0:n]) w/o bounds checks.
@@ -351,6 +358,10 @@ func karatsuba(z, x, y nat) {
}
// alias reports whether x and y share the same base array.
+// Note: alias assumes that the capacity of underlying arrays
+// is never changed for nat values; i.e. that there are
+// no 3-operand slice expressions in this code (or worse,
+// reflect-based operations to the same effect).
func alias(x, y nat) bool {
return cap(x) > 0 && cap(y) > 0 && &x[0:cap(x)][cap(x)-1] == &y[0:cap(y)][cap(y)-1]
}
@@ -377,12 +388,12 @@ func max(x, y int) int {
}
// karatsubaLen computes an approximation to the maximum k <= n such that
-// k = p<<i for a number p <= karatsubaThreshold and an i >= 0. Thus, the
+// k = p<<i for a number p <= threshold and an i >= 0. Thus, the
// result is the largest number that can be divided repeatedly by 2 before
-// becoming about the value of karatsubaThreshold.
-func karatsubaLen(n int) int {
+// becoming about the value of threshold.
+func karatsubaLen(n, threshold int) int {
i := uint(0)
- for n > karatsubaThreshold {
+ for n > threshold {
n >>= 1
i++
}
@@ -422,7 +433,7 @@ func (z nat) mul(x, y nat) nat {
// y = yh*b + y0 (0 <= y0 < b)
// b = 1<<(_W*k) ("base" of digits xi, yi)
//
- k := karatsubaLen(n)
+ k := karatsubaLen(n, karatsubaThreshold)
// k <= n
// multiply x0 and y0 via Karatsuba
@@ -475,8 +486,8 @@ func (z nat) mul(x, y nat) nat {
// basicSqr sets z = x*x and is asymptotically faster than basicMul
// by about a factor of 2, but slower for small arguments due to overhead.
-// Requirements: len(x) > 0, len(z) >= 2*len(x)
-// The (non-normalized) result is placed in z[0 : 2 * len(x)].
+// Requirements: len(x) > 0, len(z) == 2*len(x)
+// The (non-normalized) result is placed in z.
func basicSqr(z, x nat) {
n := len(x)
t := make(nat, 2*n) // temporary variable to hold the products
@@ -492,11 +503,47 @@ func basicSqr(z, x nat) {
addVV(z, z, t) // combine the result
}
+// karatsubaSqr squares x and leaves the result in z.
+// len(x) must be a power of 2 and len(z) >= 6*len(x).
+// The (non-normalized) result is placed in z[0 : 2*len(x)].
+//
+// The algorithm and the layout of z are the same as for karatsuba.
+func karatsubaSqr(z, x nat) {
+ n := len(x)
+
+ if n&1 != 0 || n < karatsubaSqrThreshold || n < 2 {
+ basicSqr(z[:2*n], x)
+ return
+ }
+
+ n2 := n >> 1
+ x1, x0 := x[n2:], x[0:n2]
+
+ karatsubaSqr(z, x0)
+ karatsubaSqr(z[n:], x1)
+
+ // s = sign(xd*yd) == -1 for xd != 0; s == 1 for xd == 0
+ xd := z[2*n : 2*n+n2]
+ if subVV(xd, x1, x0) != 0 {
+ subVV(xd, x0, x1)
+ }
+
+ p := z[n*3:]
+ karatsubaSqr(p, xd)
+
+ r := z[n*4:]
+ copy(r, z[:n*2])
+
+ karatsubaAdd(z[n2:], r, n)
+ karatsubaAdd(z[n2:], r[n:], n)
+ karatsubaSub(z[n2:], p, n) // s == -1 for p != 0; s == 1 for p == 0
+}
+
// Operands that are shorter than basicSqrThreshold are squared using
// "grade school" multiplication; for operands longer than karatsubaSqrThreshold
-// the Karatsuba algorithm is used.
+// we use the Karatsuba algorithm optimized for x == y.
var basicSqrThreshold = 20 // computed by calibrate_test.go
-var karatsubaSqrThreshold = 400 // computed by calibrate_test.go
+var karatsubaSqrThreshold = 260 // computed by calibrate_test.go
// z = x*x
func (z nat) sqr(x nat) nat {
@@ -514,18 +561,43 @@ func (z nat) sqr(x nat) nat {
if alias(z, x) {
z = nil // z is an alias for x - cannot reuse
}
- z = z.make(2 * n)
if n < basicSqrThreshold {
+ z = z.make(2 * n)
basicMul(z, x, x)
return z.norm()
}
if n < karatsubaSqrThreshold {
+ z = z.make(2 * n)
basicSqr(z, x)
return z.norm()
}
- return z.mul(x, x)
+ // Use Karatsuba multiplication optimized for x == y.
+ // The algorithm and layout of z are the same as for mul.
+
+ // z = (x1*b + x0)^2 = x1^2*b^2 + 2*x1*x0*b + x0^2
+
+ k := karatsubaLen(n, karatsubaSqrThreshold)
+
+ x0 := x[0:k]
+ z = z.make(max(6*k, 2*n))
+ karatsubaSqr(z, x0) // z = x0^2
+ z = z[0 : 2*n]
+ z[2*k:].clear()
+
+ if k < n {
+ var t nat
+ x0 := x0.norm()
+ x1 := x[k:]
+ t = t.mul(x0, x1)
+ addAt(z, t, k)
+ addAt(z, t, k) // z = 2*x1*x0*b + x0^2
+ t = t.sqr(x1)
+ addAt(z, t, 2*k) // z = x1^2*b^2 + 2*x1*x0*b + x0^2
+ }
+
+ return z.norm()
}
// mulRange computes the product of all the unsigned integers in the
@@ -718,8 +790,21 @@ func (x nat) trailingZeroBits() uint {
return i*_W + uint(bits.TrailingZeros(uint(x[i])))
}
+func same(x, y nat) bool {
+ return len(x) == len(y) && len(x) > 0 && &x[0] == &y[0]
+}
+
// z = x << s
func (z nat) shl(x nat, s uint) nat {
+ if s == 0 {
+ if same(z, x) {
+ return z
+ }
+ if !alias(z, x) {
+ return z.set(x)
+ }
+ }
+
m := len(x)
if m == 0 {
return z[:0]
@@ -736,6 +821,15 @@ func (z nat) shl(x nat, s uint) nat {
// z = x >> s
func (z nat) shr(x nat, s uint) nat {
+ if s == 0 {
+ if same(z, x) {
+ return z
+ }
+ if !alias(z, x) {
+ return z.set(x)
+ }
+ }
+
m := len(x)
n := m - int(s/_W)
if n <= 0 {
@@ -952,7 +1046,7 @@ func (z nat) expNN(x, y, m nat) nat {
// x**1 mod m == x mod m
if len(y) == 1 && y[0] == 1 && len(m) != 0 {
- _, z = z.div(z, x, m)
+ _, z = nat(nil).div(z, x, m)
return z
}
// y > 1
@@ -1125,7 +1219,7 @@ func (z nat) expNNMontgomery(x, y, m nat) nat {
// RR = 2**(2*_W*len(m)) mod m
RR := nat(nil).setWord(1)
zz := nat(nil).shl(RR, uint(2*numWords*_W))
- _, RR = RR.div(RR, zz, m)
+ _, RR = nat(nil).div(RR, zz, m)
if len(RR) < numWords {
zz = zz.make(numWords)
copy(zz, RR)
@@ -1208,25 +1302,31 @@ func (z nat) bytes(buf []byte) (i int) {
return
}
+// bigEndianWord returns the contents of buf interpreted as a big-endian encoded Word value.
+func bigEndianWord(buf []byte) Word {
+ if _W == 64 {
+ return Word(binary.BigEndian.Uint64(buf))
+ }
+ return Word(binary.BigEndian.Uint32(buf))
+}
+
// setBytes interprets buf as the bytes of a big-endian unsigned
// integer, sets z to that value, and returns z.
func (z nat) setBytes(buf []byte) nat {
z = z.make((len(buf) + _S - 1) / _S)
- k := 0
- s := uint(0)
- var d Word
- for i := len(buf); i > 0; i-- {
- d |= Word(buf[i-1]) << s
- if s += 8; s == _S*8 {
- z[k] = d
- k++
- s = 0
- d = 0
- }
+ i := len(buf)
+ for k := 0; i >= _S; k++ {
+ z[k] = bigEndianWord(buf[i-_S : i])
+ i -= _S
}
- if k < len(z) {
- z[k] = d
+ if i > 0 {
+ var d Word
+ for s := uint(0); i > 0; s += 8 {
+ d |= Word(buf[i-1]) << s
+ i--
+ }
+ z[len(z)-1] = d
}
return z.norm()
diff --git a/libgo/go/math/big/nat_test.go b/libgo/go/math/big/nat_test.go
index c25cdf0..3c79495 100644
--- a/libgo/go/math/big/nat_test.go
+++ b/libgo/go/math/big/nat_test.go
@@ -267,6 +267,34 @@ func TestShiftRight(t *testing.T) {
}
}
+func BenchmarkZeroShifts(b *testing.B) {
+ x := rndNat(800)
+
+ b.Run("Shl", func(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ var z nat
+ z.shl(x, 0)
+ }
+ })
+ b.Run("ShlSame", func(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ x.shl(x, 0)
+ }
+ })
+
+ b.Run("Shr", func(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ var z nat
+ z.shr(x, 0)
+ }
+ })
+ b.Run("ShrSame", func(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ x.shr(x, 0)
+ }
+ })
+}
+
type modWTest struct {
in string
dividend string
@@ -620,26 +648,26 @@ func TestSticky(t *testing.T) {
}
}
-func testBasicSqr(t *testing.T, x nat) {
+func testSqr(t *testing.T, x nat) {
got := make(nat, 2*len(x))
want := make(nat, 2*len(x))
- basicSqr(got, x)
- basicMul(want, x, x)
+ got = got.sqr(x)
+ want = want.mul(x, x)
if got.cmp(want) != 0 {
t.Errorf("basicSqr(%v), got %v, want %v", x, got, want)
}
}
-func TestBasicSqr(t *testing.T) {
+func TestSqr(t *testing.T) {
for _, a := range prodNN {
if a.x != nil {
- testBasicSqr(t, a.x)
+ testSqr(t, a.x)
}
if a.y != nil {
- testBasicSqr(t, a.y)
+ testSqr(t, a.y)
}
if a.z != nil {
- testBasicSqr(t, a.z)
+ testSqr(t, a.z)
}
}
}
@@ -665,3 +693,22 @@ func BenchmarkNatSqr(b *testing.B) {
})
}
}
+
+func BenchmarkNatSetBytes(b *testing.B) {
+ const maxLength = 128
+ lengths := []int{
+ // No remainder:
+ 8, 24, maxLength,
+ // With remainder:
+ 7, 23, maxLength - 1,
+ }
+ n := make(nat, maxLength/_W) // ensure n doesn't need to grow during the test
+ buf := make([]byte, maxLength)
+ for _, l := range lengths {
+ b.Run(fmt.Sprint(l), func(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ n.setBytes(buf[:l])
+ }
+ })
+ }
+}
diff --git a/libgo/go/math/big/prime.go b/libgo/go/math/big/prime.go
index 848affb..4c2c152 100644
--- a/libgo/go/math/big/prime.go
+++ b/libgo/go/math/big/prime.go
@@ -131,11 +131,11 @@ NextRandom:
//
// Baillie and Wagstaff, "Lucas Pseudoprimes", Mathematics of Computation 35(152),
// October 1980, pp. 1391-1417, especially page 1401.
-// http://www.ams.org/journals/mcom/1980-35-152/S0025-5718-1980-0583518-6/S0025-5718-1980-0583518-6.pdf
+// https://www.ams.org/journals/mcom/1980-35-152/S0025-5718-1980-0583518-6/S0025-5718-1980-0583518-6.pdf
//
// Grantham, "Frobenius Pseudoprimes", Mathematics of Computation 70(234),
// March 2000, pp. 873-891.
-// http://www.ams.org/journals/mcom/2001-70-234/S0025-5718-00-01197-2/S0025-5718-00-01197-2.pdf
+// https://www.ams.org/journals/mcom/2001-70-234/S0025-5718-00-01197-2/S0025-5718-00-01197-2.pdf
//
// Baillie, "Extra strong Lucas pseudoprimes", OEIS A217719, https://oeis.org/A217719.
//
diff --git a/libgo/go/math/big/prime_test.go b/libgo/go/math/big/prime_test.go
index 7760519..bf50f34 100644
--- a/libgo/go/math/big/prime_test.go
+++ b/libgo/go/math/big/prime_test.go
@@ -29,13 +29,13 @@ var primes = []string{
"98920366548084643601728869055592650835572950932266967461790948584315647051443",
"94560208308847015747498523884063394671606671904944666360068158221458669711639",
- // http://primes.utm.edu/lists/small/small3.html
+ // https://primes.utm.edu/lists/small/small3.html
"449417999055441493994709297093108513015373787049558499205492347871729927573118262811508386655998299074566974373711472560655026288668094291699357843464363003144674940345912431129144354948751003607115263071543163",
"230975859993204150666423538988557839555560243929065415434980904258310530753006723857139742334640122533598517597674807096648905501653461687601339782814316124971547968912893214002992086353183070342498989426570593",
"5521712099665906221540423207019333379125265462121169655563495403888449493493629943498064604536961775110765377745550377067893607246020694972959780839151452457728855382113555867743022746090187341871655890805971735385789993",
"203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123",
- // ECC primes: http://tools.ietf.org/html/draft-ladd-safecurves-02
+ // ECC primes: https://tools.ietf.org/html/draft-ladd-safecurves-02
"3618502788666131106986593281521497120414687020801267626233049500247285301239", // Curve1174: 2^251-9
"57896044618658097711785492504343953926634992332820282019728792003956564819949", // Curve25519: 2^255-19
"9850501549098619803069760025035903451269934817616361666987073351061430442874302652853566563721228910201656997576599", // E-382: 2^382-105
diff --git a/libgo/go/math/big/rat.go b/libgo/go/math/big/rat.go
index b33fc69..46d58fc 100644
--- a/libgo/go/math/big/rat.go
+++ b/libgo/go/math/big/rat.go
@@ -422,7 +422,7 @@ func (z *Rat) norm() *Rat {
neg := z.a.neg
z.a.neg = false
z.b.neg = false
- if f := NewInt(0).lehmerGCD(&z.a, &z.b); f.Cmp(intOne) != 0 {
+ if f := NewInt(0).lehmerGCD(nil, nil, &z.a, &z.b); f.Cmp(intOne) != 0 {
z.a.abs, _ = z.a.abs.div(nil, z.a.abs, f.abs)
z.b.abs, _ = z.b.abs.div(nil, z.b.abs, f.abs)
if z.b.abs.cmp(natOne) == 0 {
diff --git a/libgo/go/math/big/ratconv_test.go b/libgo/go/math/big/ratconv_test.go
index 56ac8d7..fe8b8b6 100644
--- a/libgo/go/math/big/ratconv_test.go
+++ b/libgo/go/math/big/ratconv_test.go
@@ -300,9 +300,9 @@ var float64inputs = []string{
// "1e-18446744073709551616",
// "1e+18446744073709551616",
- // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
+ // https://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
"2.2250738585072012e-308",
- // http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
+ // https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
"2.2250738585072011e-308",
// A very large number (initially wrongly parsed by the fast algorithm).
diff --git a/libgo/go/math/big/roundingmode_string.go b/libgo/go/math/big/roundingmode_string.go
index 05024b8..c7629eb 100644
--- a/libgo/go/math/big/roundingmode_string.go
+++ b/libgo/go/math/big/roundingmode_string.go
@@ -1,16 +1,16 @@
-// generated by stringer -type=RoundingMode; DO NOT EDIT
+// Code generated by "stringer -type=RoundingMode"; DO NOT EDIT.
package big
-import "fmt"
+import "strconv"
const _RoundingMode_name = "ToNearestEvenToNearestAwayToZeroAwayFromZeroToNegativeInfToPositiveInf"
var _RoundingMode_index = [...]uint8{0, 13, 26, 32, 44, 57, 70}
func (i RoundingMode) String() string {
- if i+1 >= RoundingMode(len(_RoundingMode_index)) {
- return fmt.Sprintf("RoundingMode(%d)", i)
+ if i >= RoundingMode(len(_RoundingMode_index)-1) {
+ return "RoundingMode(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _RoundingMode_name[_RoundingMode_index[i]:_RoundingMode_index[i+1]]
}
diff --git a/libgo/go/math/big/sqrt.go b/libgo/go/math/big/sqrt.go
index 00433cf..b989649 100644
--- a/libgo/go/math/big/sqrt.go
+++ b/libgo/go/math/big/sqrt.go
@@ -128,18 +128,21 @@ func (z *Float) sqrtInverse(x *Float) {
// g(t) = f(t)/f'(t) = -½t(1 - xt²)
// and the next guess is given by
// t2 = t - g(t) = ½t(3 - xt²)
- u := new(Float)
+ u := newFloat(z.prec)
+ v := newFloat(z.prec)
ng := func(t *Float) *Float {
u.prec = t.prec
+ v.prec = t.prec
u.Mul(t, t) // u = t²
u.Mul(x, u) // = xt²
- u.Sub(three, u) // = 3 - xt²
- u.Mul(t, u) // = t(3 - xt²)
+ v.Sub(three, u) // v = 3 - xt²
+ u.Mul(t, v) // u = t(3 - xt²)
return t.Mul(half, u) // = ½t(3 - xt²)
}
xf, _ := x.Float64()
- sqi := NewFloat(1 / math.Sqrt(xf))
+ sqi := newFloat(z.prec)
+ sqi.SetFloat64(1 / math.Sqrt(xf))
for prec := z.prec + 32; sqi.prec < prec; {
sqi.prec *= 2
sqi = ng(sqi)
@@ -149,3 +152,12 @@ func (z *Float) sqrtInverse(x *Float) {
// x/√x = √x
z.Mul(x, sqi)
}
+
+// newFloat returns a new *Float with space for twice the given
+// precision.
+func newFloat(prec2 uint32) *Float {
+ z := new(Float)
+ // nat.make ensures the slice length is > 0
+ z.mant = z.mant.make(int(prec2/_W) * 2)
+ return z
+}
diff --git a/libgo/go/math/bits/bits_test.go b/libgo/go/math/bits/bits_test.go
index ba05210..5c34f6d 100644
--- a/libgo/go/math/bits/bits_test.go
+++ b/libgo/go/math/bits/bits_test.go
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package bits
+package bits_test
import (
+ . "math/bits"
"testing"
"unsafe"
)
@@ -83,7 +84,7 @@ func TestLeadingZeros(t *testing.T) {
// Exported (global) variable serving as input for some
// of the benchmarks to ensure side-effect free calls
// are not optimized away.
-var Input uint64 = deBruijn64
+var Input uint64 = DeBruijn64
// Exported (global) variable to store function results
// during benchmarking to ensure side-effect free calls
@@ -333,7 +334,7 @@ func BenchmarkOnesCount64(b *testing.B) {
}
func TestRotateLeft(t *testing.T) {
- var m uint64 = deBruijn64
+ var m uint64 = DeBruijn64
for k := uint(0); k < 128; k++ {
x8 := uint8(m)
diff --git a/libgo/go/math/bits/export_test.go b/libgo/go/math/bits/export_test.go
new file mode 100644
index 0000000..8c6f933
--- /dev/null
+++ b/libgo/go/math/bits/export_test.go
@@ -0,0 +1,7 @@
+// Copyright 2018 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 bits
+
+const DeBruijn64 = deBruijn64
diff --git a/libgo/go/math/cmplx/cmath_test.go b/libgo/go/math/cmplx/cmath_test.go
index 8d70562..80c3b33 100644
--- a/libgo/go/math/cmplx/cmath_test.go
+++ b/libgo/go/math/cmplx/cmath_test.go
@@ -39,7 +39,7 @@ var vc = []complex128{
}
// The expected results below were computed by the high precision calculators
-// at http://keisan.casio.com/. More exact input values (array vc[], above)
+// at https://keisan.casio.com/. More exact input values (array vc[], above)
// were obtained by printing them with "%.26f". The answers were calculated
// to 26 digits (by using the "Digit number" drop-down control of each
// calculator).
diff --git a/libgo/go/math/erfinv.go b/libgo/go/math/erfinv.go
index 21b5578..ee423d3 100644
--- a/libgo/go/math/erfinv.go
+++ b/libgo/go/math/erfinv.go
@@ -10,7 +10,7 @@ package math
// This implementation is based on the rational approximation
// of percentage points of normal distribution available from
-// http://www.jstor.org/stable/2347330.
+// https://www.jstor.org/stable/2347330.
const (
// Coefficients for approximation to erf in |x| <= 0.85
diff --git a/libgo/go/math/example_test.go b/libgo/go/math/example_test.go
index feaf9d8..a1f764b 100644
--- a/libgo/go/math/example_test.go
+++ b/libgo/go/math/example_test.go
@@ -89,3 +89,27 @@ func ExampleSqrt() {
fmt.Printf("%.1f", c)
// Output: 5.0
}
+
+func ExampleCeil() {
+ c := math.Ceil(1.49)
+ fmt.Printf("%.1f", c)
+ // Output: 2.0
+}
+
+func ExampleFloor() {
+ c := math.Floor(1.51)
+ fmt.Printf("%.1f", c)
+ // Output: 1.0
+}
+
+func ExamplePow() {
+ c := math.Pow(2, 3)
+ fmt.Printf("%.1f", c)
+ // Output: 8.0
+}
+
+func ExamplePow10() {
+ c := math.Pow10(2)
+ fmt.Printf("%.1f", c)
+ // Output: 100.0
+}
diff --git a/libgo/go/math/floor_asm.go b/libgo/go/math/floor_asm.go
deleted file mode 100644
index 761349a..0000000
--- a/libgo/go/math/floor_asm.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2015 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.
-
-// +build ignore
-// -build amd64 amd64p32
-
-package math
-
-import "internal/cpu"
-
-var useSSE41 = cpu.X86.HasSSE41
diff --git a/libgo/go/math/hypot.go b/libgo/go/math/hypot.go
index 59b9c74..844159a 100644
--- a/libgo/go/math/hypot.go
+++ b/libgo/go/math/hypot.go
@@ -28,12 +28,7 @@ func hypot(p, q float64) float64 {
case IsNaN(p) || IsNaN(q):
return NaN()
}
- if p < 0 {
- p = -p
- }
- if q < 0 {
- q = -q
- }
+ p, q = Abs(p), Abs(q)
if p < q {
p, q = q, p
}
diff --git a/libgo/go/math/j0.go b/libgo/go/math/j0.go
index fe26791..5523fc3 100644
--- a/libgo/go/math/j0.go
+++ b/libgo/go/math/j0.go
@@ -99,9 +99,7 @@ func J0(x float64) float64 {
return 1
}
- if x < 0 {
- x = -x
- }
+ x = Abs(x)
if x >= 2 {
s, c := Sincos(x)
ss := s - c
diff --git a/libgo/go/math/ldexp.go b/libgo/go/math/ldexp.go
index e91a090c..8775cdb 100644
--- a/libgo/go/math/ldexp.go
+++ b/libgo/go/math/ldexp.go
@@ -37,7 +37,7 @@ func ldexp(frac float64, exp int) float64 {
exp += e
x := Float64bits(frac)
exp += int(x>>shift)&mask - bias
- if exp < -1074 {
+ if exp < -1075 {
return Copysign(0, frac) // underflow
}
if exp > 1023 { // overflow
@@ -48,8 +48,8 @@ func ldexp(frac float64, exp int) float64 {
}
var m float64 = 1
if exp < -1022 { // denormal
- exp += 52
- m = 1.0 / (1 << 52) // 2**-52
+ exp += 53
+ m = 1.0 / (1 << 53) // 2**-53
}
x &^= mask << shift
x |= uint64(exp+bias) << shift
diff --git a/libgo/go/math/lgamma.go b/libgo/go/math/lgamma.go
index 19ac3ffa..7af5871 100644
--- a/libgo/go/math/lgamma.go
+++ b/libgo/go/math/lgamma.go
@@ -103,7 +103,7 @@ var _lgamA = [...]float64{
4.48640949618915160150e-05, // 0x3F07858E90A45837
}
var _lgamR = [...]float64{
- 1.0, // placeholder
+ 1.0, // placeholder
1.39200533467621045958e+00, // 0x3FF645A762C4AB74
7.21935547567138069525e-01, // 0x3FE71A1893D3DCDC
1.71933865632803078993e-01, // 0x3FC601EDCCFBDF27
diff --git a/libgo/go/math/rand/exp.go b/libgo/go/math/rand/exp.go
index 4bc110f..5a8d946 100644
--- a/libgo/go/math/rand/exp.go
+++ b/libgo/go/math/rand/exp.go
@@ -13,7 +13,7 @@ import (
*
* See "The Ziggurat Method for Generating Random Variables"
* (Marsaglia & Tsang, 2000)
- * http://www.jstatsoft.org/v05/i08/paper [pdf]
+ * https://www.jstatsoft.org/v05/i08/paper [pdf]
*/
const (
diff --git a/libgo/go/math/rand/normal.go b/libgo/go/math/rand/normal.go
index ba4ea54..2c5a7aa 100644
--- a/libgo/go/math/rand/normal.go
+++ b/libgo/go/math/rand/normal.go
@@ -27,9 +27,9 @@ func absInt32(i int32) uint32 {
return uint32(i)
}
-// NormFloat64 returns a normally distributed float64 in the range
-// [-math.MaxFloat64, +math.MaxFloat64] with
-// standard normal distribution (mean = 0, stddev = 1).
+// NormFloat64 returns a normally distributed float64 in
+// the range -math.MaxFloat64 through +math.MaxFloat64 inclusive,
+// with standard normal distribution (mean = 0, stddev = 1).
// To produce a different normal distribution, callers can
// adjust the output using:
//
diff --git a/libgo/go/math/rand/rand.go b/libgo/go/math/rand/rand.go
index 147c92f..04382e6 100644
--- a/libgo/go/math/rand/rand.go
+++ b/libgo/go/math/rand/rand.go
@@ -11,6 +11,9 @@
// The default Source is safe for concurrent use by multiple goroutines, but
// Sources created by NewSource are not.
//
+// Mathematical interval notation such as [0, n) is used throughout the
+// documentation for this package.
+//
// For random numbers suitable for security-sensitive work, see the crypto/rand
// package.
package rand
diff --git a/libgo/go/math/rand/regress_test.go b/libgo/go/math/rand/regress_test.go
index e31e6c5..1f30be8 100644
--- a/libgo/go/math/rand/regress_test.go
+++ b/libgo/go/math/rand/regress_test.go
@@ -121,219 +121,219 @@ func TestRegress(t *testing.T) {
}
var regressGolden = []interface{}{
- float64(4.668112973579268), // ExpFloat64()
- float64(0.1601593871172866), // ExpFloat64()
- float64(3.0465834105636), // ExpFloat64()
- float64(0.06385839451671879), // ExpFloat64()
- float64(1.8578917487258961), // ExpFloat64()
- float64(0.784676123472182), // ExpFloat64()
- float64(0.11225477361256932), // ExpFloat64()
- float64(0.20173283329802255), // ExpFloat64()
- float64(0.3468619496201105), // ExpFloat64()
- float64(0.35601103454384536), // ExpFloat64()
- float64(0.888376329507869), // ExpFloat64()
- float64(1.4081362450365698), // ExpFloat64()
- float64(1.0077753823151994), // ExpFloat64()
- float64(0.23594100766227588), // ExpFloat64()
- float64(2.777245612300007), // ExpFloat64()
- float64(0.5202997830662377), // ExpFloat64()
- float64(1.2842705247770294), // ExpFloat64()
- float64(0.030307408362776206), // ExpFloat64()
- float64(2.204156824853721), // ExpFloat64()
- float64(2.09891923895058), // ExpFloat64()
- float32(0.94519615), // Float32()
- float32(0.24496509), // Float32()
- float32(0.65595627), // Float32()
- float32(0.05434384), // Float32()
- float32(0.3675872), // Float32()
- float32(0.28948045), // Float32()
- float32(0.1924386), // Float32()
- float32(0.65533215), // Float32()
- float32(0.8971697), // Float32()
- float32(0.16735445), // Float32()
- float32(0.28858566), // Float32()
- float32(0.9026048), // Float32()
- float32(0.84978026), // Float32()
- float32(0.2730468), // Float32()
- float32(0.6090802), // Float32()
- float32(0.253656), // Float32()
- float32(0.7746542), // Float32()
- float32(0.017480763), // Float32()
- float32(0.78707397), // Float32()
- float32(0.7993937), // Float32()
- float64(0.9451961492941164), // Float64()
- float64(0.24496508529377975), // Float64()
- float64(0.6559562651954052), // Float64()
- float64(0.05434383959970039), // Float64()
- float64(0.36758720663245853), // Float64()
- float64(0.2894804331565928), // Float64()
- float64(0.19243860967493215), // Float64()
- float64(0.6553321508148324), // Float64()
- float64(0.897169713149801), // Float64()
- float64(0.16735444255905835), // Float64()
- float64(0.2885856518054551), // Float64()
- float64(0.9026048462705047), // Float64()
- float64(0.8497802817628735), // Float64()
- float64(0.2730468047134829), // Float64()
- float64(0.6090801919903561), // Float64()
- float64(0.25365600644283687), // Float64()
- float64(0.7746542391859803), // Float64()
- float64(0.017480762156647272), // Float64()
- float64(0.7870739563039942), // Float64()
- float64(0.7993936979594545), // Float64()
- int64(8717895732742165505), // Int()
- int64(2259404117704393152), // Int()
- int64(6050128673802995827), // Int()
- int64(501233450539197794), // Int()
- int64(3390393562759376202), // Int()
- int64(2669985732393126063), // Int()
- int64(1774932891286980153), // Int()
- int64(6044372234677422456), // Int()
- int64(8274930044578894929), // Int()
- int64(1543572285742637646), // Int()
- int64(2661732831099943416), // Int()
- int64(8325060299420976708), // Int()
- int64(7837839688282259259), // Int()
- int64(2518412263346885298), // Int()
- int64(5617773211005988520), // Int()
- int64(2339563716805116249), // Int()
- int64(7144924247938981575), // Int()
- int64(161231572858529631), // Int()
- int64(7259475919510918339), // Int()
- int64(7373105480197164748), // Int()
- int32(2029793274), // Int31()
- int32(526058514), // Int31()
- int32(1408655353), // Int31()
- int32(116702506), // Int31()
- int32(789387515), // Int31()
- int32(621654496), // Int31()
- int32(413258767), // Int31()
- int32(1407315077), // Int31()
- int32(1926657288), // Int31()
- int32(359390928), // Int31()
- int32(619732968), // Int31()
- int32(1938329147), // Int31()
- int32(1824889259), // Int31()
- int32(586363548), // Int31()
- int32(1307989752), // Int31()
- int32(544722126), // Int31()
- int32(1663557311), // Int31()
- int32(37539650), // Int31()
- int32(1690228450), // Int31()
- int32(1716684894), // Int31()
- int32(0), // Int31n(1)
- int32(4), // Int31n(10)
- int32(25), // Int31n(32)
- int32(310570), // Int31n(1048576)
- int32(857611), // Int31n(1048577)
- int32(621654496), // Int31n(1000000000)
- int32(413258767), // Int31n(1073741824)
- int32(1407315077), // Int31n(2147483646)
- int32(1926657288), // Int31n(2147483647)
- int32(0), // Int31n(1)
- int32(8), // Int31n(10)
- int32(27), // Int31n(32)
- int32(367019), // Int31n(1048576)
- int32(209005), // Int31n(1048577)
- int32(307989752), // Int31n(1000000000)
- int32(544722126), // Int31n(1073741824)
- int32(1663557311), // Int31n(2147483646)
- int32(37539650), // Int31n(2147483647)
- int32(0), // Int31n(1)
- int32(4), // Int31n(10)
- int64(8717895732742165505), // Int63()
- int64(2259404117704393152), // Int63()
- int64(6050128673802995827), // Int63()
- int64(501233450539197794), // Int63()
- int64(3390393562759376202), // Int63()
- int64(2669985732393126063), // Int63()
- int64(1774932891286980153), // Int63()
- int64(6044372234677422456), // Int63()
- int64(8274930044578894929), // Int63()
- int64(1543572285742637646), // Int63()
- int64(2661732831099943416), // Int63()
- int64(8325060299420976708), // Int63()
- int64(7837839688282259259), // Int63()
- int64(2518412263346885298), // Int63()
- int64(5617773211005988520), // Int63()
- int64(2339563716805116249), // Int63()
- int64(7144924247938981575), // Int63()
- int64(161231572858529631), // Int63()
- int64(7259475919510918339), // Int63()
- int64(7373105480197164748), // Int63()
- int64(0), // Int63n(1)
- int64(2), // Int63n(10)
- int64(19), // Int63n(32)
- int64(959842), // Int63n(1048576)
- int64(688912), // Int63n(1048577)
- int64(393126063), // Int63n(1000000000)
- int64(89212473), // Int63n(1073741824)
- int64(834026388), // Int63n(2147483646)
- int64(1577188963), // Int63n(2147483647)
- int64(543572285742637646), // Int63n(1000000000000000000)
- int64(355889821886249464), // Int63n(1152921504606846976)
- int64(8325060299420976708), // Int63n(9223372036854775806)
- int64(7837839688282259259), // Int63n(9223372036854775807)
- int64(0), // Int63n(1)
- int64(0), // Int63n(10)
- int64(25), // Int63n(32)
- int64(679623), // Int63n(1048576)
- int64(882178), // Int63n(1048577)
- int64(510918339), // Int63n(1000000000)
- int64(782454476), // Int63n(1073741824)
- int64(0), // Intn(1)
- int64(4), // Intn(10)
- int64(25), // Intn(32)
- int64(310570), // Intn(1048576)
- int64(857611), // Intn(1048577)
- int64(621654496), // Intn(1000000000)
- int64(413258767), // Intn(1073741824)
- int64(1407315077), // Intn(2147483646)
- int64(1926657288), // Intn(2147483647)
- int64(543572285742637646), // Intn(1000000000000000000)
- int64(355889821886249464), // Intn(1152921504606846976)
- int64(8325060299420976708), // Intn(9223372036854775806)
- int64(7837839688282259259), // Intn(9223372036854775807)
- int64(0), // Intn(1)
- int64(2), // Intn(10)
- int64(14), // Intn(32)
- int64(515775), // Intn(1048576)
- int64(839455), // Intn(1048577)
- int64(690228450), // Intn(1000000000)
- int64(642943070), // Intn(1073741824)
- float64(-0.28158587086436215), // NormFloat64()
- float64(0.570933095808067), // NormFloat64()
- float64(-1.6920196326157044), // NormFloat64()
- float64(0.1996229111693099), // NormFloat64()
- float64(1.9195199291234621), // NormFloat64()
- float64(0.8954838794918353), // NormFloat64()
- float64(0.41457072128813166), // NormFloat64()
- float64(-0.48700161491544713), // NormFloat64()
- float64(-0.1684059662402393), // NormFloat64()
- float64(0.37056410998929545), // NormFloat64()
- float64(1.0156889027029008), // NormFloat64()
- float64(-0.5174422210625114), // NormFloat64()
- float64(-0.5565834214413804), // NormFloat64()
- float64(0.778320596648391), // NormFloat64()
- float64(-1.8970718197702225), // NormFloat64()
- float64(0.5229525761688676), // NormFloat64()
- float64(-1.5515595563231523), // NormFloat64()
- float64(0.0182029289376123), // NormFloat64()
- float64(-0.6820951356608795), // NormFloat64()
- float64(-0.5987943422687668), // NormFloat64()
- []int{}, // Perm(0)
- []int{0}, // Perm(1)
- []int{0, 4, 1, 3, 2}, // Perm(5)
- []int{3, 1, 0, 4, 7, 5, 2, 6}, // Perm(8)
- []int{5, 0, 3, 6, 7, 4, 2, 1, 8}, // Perm(9)
- []int{4, 5, 0, 2, 6, 9, 3, 1, 8, 7}, // Perm(10)
+ float64(4.668112973579268), // ExpFloat64()
+ float64(0.1601593871172866), // ExpFloat64()
+ float64(3.0465834105636), // ExpFloat64()
+ float64(0.06385839451671879), // ExpFloat64()
+ float64(1.8578917487258961), // ExpFloat64()
+ float64(0.784676123472182), // ExpFloat64()
+ float64(0.11225477361256932), // ExpFloat64()
+ float64(0.20173283329802255), // ExpFloat64()
+ float64(0.3468619496201105), // ExpFloat64()
+ float64(0.35601103454384536), // ExpFloat64()
+ float64(0.888376329507869), // ExpFloat64()
+ float64(1.4081362450365698), // ExpFloat64()
+ float64(1.0077753823151994), // ExpFloat64()
+ float64(0.23594100766227588), // ExpFloat64()
+ float64(2.777245612300007), // ExpFloat64()
+ float64(0.5202997830662377), // ExpFloat64()
+ float64(1.2842705247770294), // ExpFloat64()
+ float64(0.030307408362776206), // ExpFloat64()
+ float64(2.204156824853721), // ExpFloat64()
+ float64(2.09891923895058), // ExpFloat64()
+ float32(0.94519615), // Float32()
+ float32(0.24496509), // Float32()
+ float32(0.65595627), // Float32()
+ float32(0.05434384), // Float32()
+ float32(0.3675872), // Float32()
+ float32(0.28948045), // Float32()
+ float32(0.1924386), // Float32()
+ float32(0.65533215), // Float32()
+ float32(0.8971697), // Float32()
+ float32(0.16735445), // Float32()
+ float32(0.28858566), // Float32()
+ float32(0.9026048), // Float32()
+ float32(0.84978026), // Float32()
+ float32(0.2730468), // Float32()
+ float32(0.6090802), // Float32()
+ float32(0.253656), // Float32()
+ float32(0.7746542), // Float32()
+ float32(0.017480763), // Float32()
+ float32(0.78707397), // Float32()
+ float32(0.7993937), // Float32()
+ float64(0.9451961492941164), // Float64()
+ float64(0.24496508529377975), // Float64()
+ float64(0.6559562651954052), // Float64()
+ float64(0.05434383959970039), // Float64()
+ float64(0.36758720663245853), // Float64()
+ float64(0.2894804331565928), // Float64()
+ float64(0.19243860967493215), // Float64()
+ float64(0.6553321508148324), // Float64()
+ float64(0.897169713149801), // Float64()
+ float64(0.16735444255905835), // Float64()
+ float64(0.2885856518054551), // Float64()
+ float64(0.9026048462705047), // Float64()
+ float64(0.8497802817628735), // Float64()
+ float64(0.2730468047134829), // Float64()
+ float64(0.6090801919903561), // Float64()
+ float64(0.25365600644283687), // Float64()
+ float64(0.7746542391859803), // Float64()
+ float64(0.017480762156647272), // Float64()
+ float64(0.7870739563039942), // Float64()
+ float64(0.7993936979594545), // Float64()
+ int64(8717895732742165505), // Int()
+ int64(2259404117704393152), // Int()
+ int64(6050128673802995827), // Int()
+ int64(501233450539197794), // Int()
+ int64(3390393562759376202), // Int()
+ int64(2669985732393126063), // Int()
+ int64(1774932891286980153), // Int()
+ int64(6044372234677422456), // Int()
+ int64(8274930044578894929), // Int()
+ int64(1543572285742637646), // Int()
+ int64(2661732831099943416), // Int()
+ int64(8325060299420976708), // Int()
+ int64(7837839688282259259), // Int()
+ int64(2518412263346885298), // Int()
+ int64(5617773211005988520), // Int()
+ int64(2339563716805116249), // Int()
+ int64(7144924247938981575), // Int()
+ int64(161231572858529631), // Int()
+ int64(7259475919510918339), // Int()
+ int64(7373105480197164748), // Int()
+ int32(2029793274), // Int31()
+ int32(526058514), // Int31()
+ int32(1408655353), // Int31()
+ int32(116702506), // Int31()
+ int32(789387515), // Int31()
+ int32(621654496), // Int31()
+ int32(413258767), // Int31()
+ int32(1407315077), // Int31()
+ int32(1926657288), // Int31()
+ int32(359390928), // Int31()
+ int32(619732968), // Int31()
+ int32(1938329147), // Int31()
+ int32(1824889259), // Int31()
+ int32(586363548), // Int31()
+ int32(1307989752), // Int31()
+ int32(544722126), // Int31()
+ int32(1663557311), // Int31()
+ int32(37539650), // Int31()
+ int32(1690228450), // Int31()
+ int32(1716684894), // Int31()
+ int32(0), // Int31n(1)
+ int32(4), // Int31n(10)
+ int32(25), // Int31n(32)
+ int32(310570), // Int31n(1048576)
+ int32(857611), // Int31n(1048577)
+ int32(621654496), // Int31n(1000000000)
+ int32(413258767), // Int31n(1073741824)
+ int32(1407315077), // Int31n(2147483646)
+ int32(1926657288), // Int31n(2147483647)
+ int32(0), // Int31n(1)
+ int32(8), // Int31n(10)
+ int32(27), // Int31n(32)
+ int32(367019), // Int31n(1048576)
+ int32(209005), // Int31n(1048577)
+ int32(307989752), // Int31n(1000000000)
+ int32(544722126), // Int31n(1073741824)
+ int32(1663557311), // Int31n(2147483646)
+ int32(37539650), // Int31n(2147483647)
+ int32(0), // Int31n(1)
+ int32(4), // Int31n(10)
+ int64(8717895732742165505), // Int63()
+ int64(2259404117704393152), // Int63()
+ int64(6050128673802995827), // Int63()
+ int64(501233450539197794), // Int63()
+ int64(3390393562759376202), // Int63()
+ int64(2669985732393126063), // Int63()
+ int64(1774932891286980153), // Int63()
+ int64(6044372234677422456), // Int63()
+ int64(8274930044578894929), // Int63()
+ int64(1543572285742637646), // Int63()
+ int64(2661732831099943416), // Int63()
+ int64(8325060299420976708), // Int63()
+ int64(7837839688282259259), // Int63()
+ int64(2518412263346885298), // Int63()
+ int64(5617773211005988520), // Int63()
+ int64(2339563716805116249), // Int63()
+ int64(7144924247938981575), // Int63()
+ int64(161231572858529631), // Int63()
+ int64(7259475919510918339), // Int63()
+ int64(7373105480197164748), // Int63()
+ int64(0), // Int63n(1)
+ int64(2), // Int63n(10)
+ int64(19), // Int63n(32)
+ int64(959842), // Int63n(1048576)
+ int64(688912), // Int63n(1048577)
+ int64(393126063), // Int63n(1000000000)
+ int64(89212473), // Int63n(1073741824)
+ int64(834026388), // Int63n(2147483646)
+ int64(1577188963), // Int63n(2147483647)
+ int64(543572285742637646), // Int63n(1000000000000000000)
+ int64(355889821886249464), // Int63n(1152921504606846976)
+ int64(8325060299420976708), // Int63n(9223372036854775806)
+ int64(7837839688282259259), // Int63n(9223372036854775807)
+ int64(0), // Int63n(1)
+ int64(0), // Int63n(10)
+ int64(25), // Int63n(32)
+ int64(679623), // Int63n(1048576)
+ int64(882178), // Int63n(1048577)
+ int64(510918339), // Int63n(1000000000)
+ int64(782454476), // Int63n(1073741824)
+ int64(0), // Intn(1)
+ int64(4), // Intn(10)
+ int64(25), // Intn(32)
+ int64(310570), // Intn(1048576)
+ int64(857611), // Intn(1048577)
+ int64(621654496), // Intn(1000000000)
+ int64(413258767), // Intn(1073741824)
+ int64(1407315077), // Intn(2147483646)
+ int64(1926657288), // Intn(2147483647)
+ int64(543572285742637646), // Intn(1000000000000000000)
+ int64(355889821886249464), // Intn(1152921504606846976)
+ int64(8325060299420976708), // Intn(9223372036854775806)
+ int64(7837839688282259259), // Intn(9223372036854775807)
+ int64(0), // Intn(1)
+ int64(2), // Intn(10)
+ int64(14), // Intn(32)
+ int64(515775), // Intn(1048576)
+ int64(839455), // Intn(1048577)
+ int64(690228450), // Intn(1000000000)
+ int64(642943070), // Intn(1073741824)
+ float64(-0.28158587086436215), // NormFloat64()
+ float64(0.570933095808067), // NormFloat64()
+ float64(-1.6920196326157044), // NormFloat64()
+ float64(0.1996229111693099), // NormFloat64()
+ float64(1.9195199291234621), // NormFloat64()
+ float64(0.8954838794918353), // NormFloat64()
+ float64(0.41457072128813166), // NormFloat64()
+ float64(-0.48700161491544713), // NormFloat64()
+ float64(-0.1684059662402393), // NormFloat64()
+ float64(0.37056410998929545), // NormFloat64()
+ float64(1.0156889027029008), // NormFloat64()
+ float64(-0.5174422210625114), // NormFloat64()
+ float64(-0.5565834214413804), // NormFloat64()
+ float64(0.778320596648391), // NormFloat64()
+ float64(-1.8970718197702225), // NormFloat64()
+ float64(0.5229525761688676), // NormFloat64()
+ float64(-1.5515595563231523), // NormFloat64()
+ float64(0.0182029289376123), // NormFloat64()
+ float64(-0.6820951356608795), // NormFloat64()
+ float64(-0.5987943422687668), // NormFloat64()
+ []int{}, // Perm(0)
+ []int{0}, // Perm(1)
+ []int{0, 4, 1, 3, 2}, // Perm(5)
+ []int{3, 1, 0, 4, 7, 5, 2, 6}, // Perm(8)
+ []int{5, 0, 3, 6, 7, 4, 2, 1, 8}, // Perm(9)
+ []int{4, 5, 0, 2, 6, 9, 3, 1, 8, 7}, // Perm(10)
[]int{14, 2, 0, 8, 3, 5, 13, 12, 1, 4, 6, 7, 11, 9, 15, 10}, // Perm(16)
- []int{}, // Perm(0)
- []int{0}, // Perm(1)
- []int{3, 0, 1, 2, 4}, // Perm(5)
- []int{5, 1, 2, 0, 4, 7, 3, 6}, // Perm(8)
- []int{4, 0, 6, 8, 1, 5, 2, 7, 3}, // Perm(9)
- []int{8, 6, 1, 7, 5, 4, 3, 2, 9, 0}, // Perm(10)
+ []int{}, // Perm(0)
+ []int{0}, // Perm(1)
+ []int{3, 0, 1, 2, 4}, // Perm(5)
+ []int{5, 1, 2, 0, 4, 7, 3, 6}, // Perm(8)
+ []int{4, 0, 6, 8, 1, 5, 2, 7, 3}, // Perm(9)
+ []int{8, 6, 1, 7, 5, 4, 3, 2, 9, 0}, // Perm(10)
[]int{0, 3, 13, 2, 15, 4, 10, 1, 8, 14, 7, 6, 12, 9, 5, 11}, // Perm(16)
[]int{}, // Perm(0)
[]int{0}, // Perm(1)
@@ -346,7 +346,7 @@ var regressGolden = []interface{}{
[]byte{0x41, 0xd3, 0xff, 0x12, 0x4, 0x5b, 0x73, 0xc8}, // Read([0 0 0 0 0 0 0 0])
[]byte{0x6e, 0x4f, 0xf9, 0x5f, 0xf6, 0x62, 0xa5, 0xee, 0xe8}, // Read([0 0 0 0 0 0 0 0 0])
[]byte{0x2a, 0xbd, 0xf4, 0x4a, 0x2d, 0xb, 0x75, 0xfb, 0x18, 0xd}, // Read([0 0 0 0 0 0 0 0 0 0])
- []byte{0xaf}, // Read([0])
+ []byte{0xaf}, // Read([0])
[]byte{0x48, 0xa7, 0x9e, 0xe0, 0xb1, 0xd, 0x39}, // Read([0 0 0 0 0 0 0])
[]byte{0x46, 0x51, 0x85, 0xf, 0xd4, 0xa1, 0x78, 0x89}, // Read([0 0 0 0 0 0 0 0])
[]byte{0x2e, 0xe2, 0x85, 0xec, 0xe1, 0x51, 0x14, 0x55, 0x78}, // Read([0 0 0 0 0 0 0 0 0])
@@ -356,49 +356,49 @@ var regressGolden = []interface{}{
[]byte{0xc6, 0xb1, 0xf8, 0x3b, 0x8e, 0x88, 0x3b, 0xbf}, // Read([0 0 0 0 0 0 0 0])
[]byte{0x85, 0x7a, 0xab, 0x99, 0xc5, 0xb2, 0x52, 0xc7, 0x42}, // Read([0 0 0 0 0 0 0 0 0])
[]byte{0x9c, 0x32, 0xf3, 0xa8, 0xae, 0xb7, 0x9e, 0xf8, 0x56, 0xf6}, // Read([0 0 0 0 0 0 0 0 0 0])
- []byte{0x59}, // Read([0])
+ []byte{0x59}, // Read([0])
[]byte{0xc1, 0x8f, 0xd, 0xce, 0xcc, 0x77, 0xc7}, // Read([0 0 0 0 0 0 0])
[]byte{0x5e, 0x7a, 0x81, 0xbf, 0xde, 0x27, 0x5f, 0x67}, // Read([0 0 0 0 0 0 0 0])
[]byte{0xcf, 0xe2, 0x42, 0xcf, 0x3c, 0xc3, 0x54, 0xf3, 0xed}, // Read([0 0 0 0 0 0 0 0 0])
[]byte{0xe2, 0xd6, 0xbe, 0xcc, 0x4e, 0xa3, 0xae, 0x5e, 0x88, 0x52}, // Read([0 0 0 0 0 0 0 0 0 0])
- uint32(4059586549), // Uint32()
- uint32(1052117029), // Uint32()
- uint32(2817310706), // Uint32()
- uint32(233405013), // Uint32()
- uint32(1578775030), // Uint32()
- uint32(1243308993), // Uint32()
- uint32(826517535), // Uint32()
- uint32(2814630155), // Uint32()
- uint32(3853314576), // Uint32()
- uint32(718781857), // Uint32()
- uint32(1239465936), // Uint32()
- uint32(3876658295), // Uint32()
- uint32(3649778518), // Uint32()
- uint32(1172727096), // Uint32()
- uint32(2615979505), // Uint32()
- uint32(1089444252), // Uint32()
- uint32(3327114623), // Uint32()
- uint32(75079301), // Uint32()
- uint32(3380456901), // Uint32()
- uint32(3433369789), // Uint32()
- uint64(8717895732742165505), // Uint64()
- uint64(2259404117704393152), // Uint64()
- uint64(6050128673802995827), // Uint64()
- uint64(9724605487393973602), // Uint64()
- uint64(12613765599614152010), // Uint64()
- uint64(11893357769247901871), // Uint64()
- uint64(1774932891286980153), // Uint64()
- uint64(15267744271532198264), // Uint64()
- uint64(17498302081433670737), // Uint64()
- uint64(1543572285742637646), // Uint64()
- uint64(11885104867954719224), // Uint64()
- uint64(17548432336275752516), // Uint64()
- uint64(7837839688282259259), // Uint64()
- uint64(2518412263346885298), // Uint64()
- uint64(5617773211005988520), // Uint64()
- uint64(11562935753659892057), // Uint64()
- uint64(16368296284793757383), // Uint64()
- uint64(161231572858529631), // Uint64()
- uint64(16482847956365694147), // Uint64()
- uint64(16596477517051940556), // Uint64()
+ uint32(4059586549), // Uint32()
+ uint32(1052117029), // Uint32()
+ uint32(2817310706), // Uint32()
+ uint32(233405013), // Uint32()
+ uint32(1578775030), // Uint32()
+ uint32(1243308993), // Uint32()
+ uint32(826517535), // Uint32()
+ uint32(2814630155), // Uint32()
+ uint32(3853314576), // Uint32()
+ uint32(718781857), // Uint32()
+ uint32(1239465936), // Uint32()
+ uint32(3876658295), // Uint32()
+ uint32(3649778518), // Uint32()
+ uint32(1172727096), // Uint32()
+ uint32(2615979505), // Uint32()
+ uint32(1089444252), // Uint32()
+ uint32(3327114623), // Uint32()
+ uint32(75079301), // Uint32()
+ uint32(3380456901), // Uint32()
+ uint32(3433369789), // Uint32()
+ uint64(8717895732742165505), // Uint64()
+ uint64(2259404117704393152), // Uint64()
+ uint64(6050128673802995827), // Uint64()
+ uint64(9724605487393973602), // Uint64()
+ uint64(12613765599614152010), // Uint64()
+ uint64(11893357769247901871), // Uint64()
+ uint64(1774932891286980153), // Uint64()
+ uint64(15267744271532198264), // Uint64()
+ uint64(17498302081433670737), // Uint64()
+ uint64(1543572285742637646), // Uint64()
+ uint64(11885104867954719224), // Uint64()
+ uint64(17548432336275752516), // Uint64()
+ uint64(7837839688282259259), // Uint64()
+ uint64(2518412263346885298), // Uint64()
+ uint64(5617773211005988520), // Uint64()
+ uint64(11562935753659892057), // Uint64()
+ uint64(16368296284793757383), // Uint64()
+ uint64(161231572858529631), // Uint64()
+ uint64(16482847956365694147), // Uint64()
+ uint64(16596477517051940556), // Uint64()
}
diff --git a/libgo/go/math/rand/rng.go b/libgo/go/math/rand/rng.go
index f922417..f305df1 100644
--- a/libgo/go/math/rand/rng.go
+++ b/libgo/go/math/rand/rng.go
@@ -12,19 +12,16 @@ package rand
*/
const (
- _LEN = 607
- _TAP = 273
- _MAX = 1 << 63
- _MASK = _MAX - 1
- _A = 48271
- _M = (1 << 31) - 1
- _Q = 44488
- _R = 3399
+ rngLen = 607
+ rngTap = 273
+ rngMax = 1 << 63
+ rngMask = rngMax - 1
+ int32max = (1 << 31) - 1
)
var (
- // Used for seeding. See gen_cooked.go for details.
- rng_cooked [_LEN]int64 = [...]int64{
+ // rngCooked used for seeding. See gen_cooked.go for details.
+ rngCooked [rngLen]int64 = [...]int64{
-4181792142133755926, -4576982950128230565, 1395769623340756751, 5333664234075297259,
-6347679516498800754, 9033628115061424579, 7143218595135194537, 4812947590706362721,
7937252194349799378, 5307299880338848416, 8209348851763925077, -7107630437535961764,
@@ -181,18 +178,24 @@ var (
)
type rngSource struct {
- tap int // index into vec
- feed int // index into vec
- vec [_LEN]int64 // current feedback register
+ tap int // index into vec
+ feed int // index into vec
+ vec [rngLen]int64 // current feedback register
}
// seed rng x[n+1] = 48271 * x[n] mod (2**31 - 1)
func seedrand(x int32) int32 {
- hi := x / _Q
- lo := x % _Q
- x = _A*lo - _R*hi
+ const (
+ A = 48271
+ Q = 44488
+ R = 3399
+ )
+
+ hi := x / Q
+ lo := x % Q
+ x = A*lo - R*hi
if x < 0 {
- x += _M
+ x += int32max
}
return x
}
@@ -200,18 +203,18 @@ func seedrand(x int32) int32 {
// Seed uses the provided seed value to initialize the generator to a deterministic state.
func (rng *rngSource) Seed(seed int64) {
rng.tap = 0
- rng.feed = _LEN - _TAP
+ rng.feed = rngLen - rngTap
- seed = seed % _M
+ seed = seed % int32max
if seed < 0 {
- seed += _M
+ seed += int32max
}
if seed == 0 {
seed = 89482311
}
x := int32(seed)
- for i := -20; i < _LEN; i++ {
+ for i := -20; i < rngLen; i++ {
x = seedrand(x)
if i >= 0 {
var u int64
@@ -220,7 +223,7 @@ func (rng *rngSource) Seed(seed int64) {
u ^= int64(x) << 20
x = seedrand(x)
u ^= int64(x)
- u ^= rng_cooked[i]
+ u ^= rngCooked[i]
rng.vec[i] = u
}
}
@@ -228,19 +231,19 @@ func (rng *rngSource) Seed(seed int64) {
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
func (rng *rngSource) Int63() int64 {
- return int64(rng.Uint64() & _MASK)
+ return int64(rng.Uint64() & rngMask)
}
// Uint64 returns a non-negative pseudo-random 64-bit integer as an uint64.
func (rng *rngSource) Uint64() uint64 {
rng.tap--
if rng.tap < 0 {
- rng.tap += _LEN
+ rng.tap += rngLen
}
rng.feed--
if rng.feed < 0 {
- rng.feed += _LEN
+ rng.feed += rngLen
}
x := rng.vec[rng.feed] + rng.vec[rng.tap]
diff --git a/libgo/go/math/sin.go b/libgo/go/math/sin.go
index 75579ab..e3166e2 100644
--- a/libgo/go/math/sin.go
+++ b/libgo/go/math/sin.go
@@ -137,9 +137,7 @@ func cos(x float64) float64 {
// make argument positive
sign := false
- if x < 0 {
- x = -x
- }
+ x = Abs(x)
j := int64(x * M4PI) // integer part of x/(Pi/4), as integer for tests on the phase angle
y := float64(j) // integer part of x/(Pi/4), as float
diff --git a/libgo/go/math/sinh.go b/libgo/go/math/sinh.go
index 139b911..9dff71e 100644
--- a/libgo/go/math/sinh.go
+++ b/libgo/go/math/sinh.go
@@ -43,10 +43,11 @@ func Sinh(x float64) float64 {
var temp float64
switch true {
case x > 21:
- temp = Exp(x) / 2
+ temp = Exp(x) * 0.5
case x > 0.5:
- temp = (Exp(x) - Exp(-x)) / 2
+ ex := Exp(x)
+ temp = (ex - 1/ex) * 0.5
default:
sq := x * x
@@ -67,11 +68,10 @@ func Sinh(x float64) float64 {
// Cosh(±Inf) = +Inf
// Cosh(NaN) = NaN
func Cosh(x float64) float64 {
- if x < 0 {
- x = -x
- }
+ x = Abs(x)
if x > 21 {
- return Exp(x) / 2
+ return Exp(x) * 0.5
}
- return (Exp(x) + Exp(-x)) / 2
+ ex := Exp(x)
+ return (ex + 1/ex) * 0.5
}