cmd/dist: copy needed packages from standard library during bootstrap
This allows use of newer math/big (and later debug/pe)
without maintaining a vendored copy somewhere in cmd.
Use for math/big, deleting cmd/compile/internal/big.
Change-Id: I2bffa7a9ef115015be29fafdb02acc3e7a665d11
Reviewed-on: https://go-review.googlesource.com/31010
Reviewed-by: Minux Ma <minux@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/src/cmd/compile/fmt_test.go b/src/cmd/compile/fmt_test.go
index 48999ae..424131d 100644
--- a/src/cmd/compile/fmt_test.go
+++ b/src/cmd/compile/fmt_test.go
@@ -506,9 +506,7 @@
// blacklistedPackages is the set of packages which can
// be ignored.
-var blacklistedPackages = map[string]bool{
- "cmd/compile/internal/big": true,
-}
+var blacklistedPackages = map[string]bool{}
// blacklistedFunctions is the set of functions which may have
// format-like arguments but which don't do any formatting and
@@ -537,7 +535,7 @@
// To print out a new table, run: go test -run Formats -v.
var knownFormats = map[string]string{
"*bytes.Buffer %s": "",
- "*cmd/compile/internal/big.Int %#x": "",
+ "*math/big.Int %#x": "",
"*cmd/compile/internal/gc.Bits %v": "",
"*cmd/compile/internal/gc.Field %p": "",
"*cmd/compile/internal/gc.Field %v": "",
diff --git a/src/cmd/compile/internal/big/accuracy_string.go b/src/cmd/compile/internal/big/accuracy_string.go
deleted file mode 100644
index 24ef7f1..0000000
--- a/src/cmd/compile/internal/big/accuracy_string.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// generated by stringer -type=Accuracy; DO NOT EDIT
-
-package big
-
-import "fmt"
-
-const _Accuracy_name = "BelowExactAbove"
-
-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)
- }
- return _Accuracy_name[_Accuracy_index[i]:_Accuracy_index[i+1]]
-}
diff --git a/src/cmd/compile/internal/big/arith.go b/src/cmd/compile/internal/big/arith.go
deleted file mode 100644
index d7ea838..0000000
--- a/src/cmd/compile/internal/big/arith.go
+++ /dev/null
@@ -1,305 +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.
-
-// This file provides Go implementations of elementary multi-precision
-// arithmetic operations on word vectors. Needed for platforms without
-// assembly implementations of these routines.
-
-package big
-
-// A Word represents a single digit of a multi-precision unsigned integer.
-type Word uintptr
-
-const (
- // Compute the size _S of a Word in bytes.
- _m = ^Word(0)
- _logS = _m>>8&1 + _m>>16&1 + _m>>32&1
- _S = 1 << _logS
-
- _W = _S << 3 // word size in bits
- _B = 1 << _W // digit base
- _M = _B - 1 // digit mask
-
- _W2 = _W / 2 // half word size in bits
- _B2 = 1 << _W2 // half digit base
- _M2 = _B2 - 1 // half digit mask
-)
-
-// ----------------------------------------------------------------------------
-// Elementary operations on words
-//
-// These operations are used by the vector operations below.
-
-// z1<<_W + z0 = x+y+c, with c == 0 or 1
-func addWW_g(x, y, c Word) (z1, z0 Word) {
- yc := y + c
- z0 = x + yc
- if z0 < x || yc < y {
- z1 = 1
- }
- return
-}
-
-// z1<<_W + z0 = x-y-c, with c == 0 or 1
-func subWW_g(x, y, c Word) (z1, z0 Word) {
- yc := y + c
- z0 = x - yc
- if z0 > x || yc < y {
- z1 = 1
- }
- return
-}
-
-// z1<<_W + z0 = x*y
-// Adapted from Warren, Hacker's Delight, p. 132.
-func mulWW_g(x, y Word) (z1, z0 Word) {
- x0 := x & _M2
- x1 := x >> _W2
- y0 := y & _M2
- y1 := y >> _W2
- w0 := x0 * y0
- t := x1*y0 + w0>>_W2
- w1 := t & _M2
- w2 := t >> _W2
- w1 += x0 * y1
- z1 = x1*y1 + w2 + w1>>_W2
- z0 = x * y
- return
-}
-
-// z1<<_W + z0 = x*y + c
-func mulAddWWW_g(x, y, c Word) (z1, z0 Word) {
- z1, zz0 := mulWW_g(x, y)
- if z0 = zz0 + c; z0 < zz0 {
- z1++
- }
- return
-}
-
-// Length of x in bits.
-func bitLen_g(x Word) (n int) {
- for ; x >= 0x8000; x >>= 16 {
- n += 16
- }
- if x >= 0x80 {
- x >>= 8
- n += 8
- }
- if x >= 0x8 {
- x >>= 4
- n += 4
- }
- if x >= 0x2 {
- x >>= 2
- n += 2
- }
- if x >= 0x1 {
- n++
- }
- return
-}
-
-// log2 computes the integer binary logarithm of x.
-// The result is the integer n for which 2^n <= x < 2^(n+1).
-// If x == 0, the result is -1.
-func log2(x Word) int {
- return bitLen(x) - 1
-}
-
-// nlz returns the number of leading zeros in x.
-func nlz(x Word) uint {
- return uint(_W - bitLen(x))
-}
-
-// nlz64 returns the number of leading zeros in x.
-func nlz64(x uint64) uint {
- switch _W {
- case 32:
- w := x >> 32
- if w == 0 {
- return 32 + nlz(Word(x))
- }
- return nlz(Word(w))
- case 64:
- return nlz(Word(x))
- }
- panic("unreachable")
-}
-
-// q = (u1<<_W + u0 - r)/y
-// Adapted from Warren, Hacker's Delight, p. 152.
-func divWW_g(u1, u0, v Word) (q, r Word) {
- if u1 >= v {
- return 1<<_W - 1, 1<<_W - 1
- }
-
- s := nlz(v)
- v <<= s
-
- vn1 := v >> _W2
- vn0 := v & _M2
- un32 := u1<<s | u0>>(_W-s)
- un10 := u0 << s
- un1 := un10 >> _W2
- un0 := un10 & _M2
- q1 := un32 / vn1
- rhat := un32 - q1*vn1
-
- for q1 >= _B2 || q1*vn0 > _B2*rhat+un1 {
- q1--
- rhat += vn1
- if rhat >= _B2 {
- break
- }
- }
-
- un21 := un32*_B2 + un1 - q1*v
- q0 := un21 / vn1
- rhat = un21 - q0*vn1
-
- for q0 >= _B2 || q0*vn0 > _B2*rhat+un0 {
- q0--
- rhat += vn1
- if rhat >= _B2 {
- break
- }
- }
-
- return q1*_B2 + q0, (un21*_B2 + un0 - q0*v) >> s
-}
-
-// Keep for performance debugging.
-// Using addWW_g is likely slower.
-const use_addWW_g = false
-
-// The resulting carry c is either 0 or 1.
-func addVV_g(z, x, y []Word) (c Word) {
- if use_addWW_g {
- for i := range z {
- c, z[i] = addWW_g(x[i], y[i], c)
- }
- return
- }
-
- for i, xi := range x[:len(z)] {
- yi := y[i]
- zi := xi + yi + c
- z[i] = zi
- // see "Hacker's Delight", section 2-12 (overflow detection)
- c = (xi&yi | (xi|yi)&^zi) >> (_W - 1)
- }
- return
-}
-
-// The resulting carry c is either 0 or 1.
-func subVV_g(z, x, y []Word) (c Word) {
- if use_addWW_g {
- for i := range z {
- c, z[i] = subWW_g(x[i], y[i], c)
- }
- return
- }
-
- for i, xi := range x[:len(z)] {
- yi := y[i]
- zi := xi - yi - c
- z[i] = zi
- // see "Hacker's Delight", section 2-12 (overflow detection)
- c = (yi&^xi | (yi|^xi)&zi) >> (_W - 1)
- }
- return
-}
-
-// The resulting carry c is either 0 or 1.
-func addVW_g(z, x []Word, y Word) (c Word) {
- if use_addWW_g {
- c = y
- for i := range z {
- c, z[i] = addWW_g(x[i], c, 0)
- }
- return
- }
-
- c = y
- for i, xi := range x[:len(z)] {
- zi := xi + c
- z[i] = zi
- c = xi &^ zi >> (_W - 1)
- }
- return
-}
-
-func subVW_g(z, x []Word, y Word) (c Word) {
- if use_addWW_g {
- c = y
- for i := range z {
- c, z[i] = subWW_g(x[i], c, 0)
- }
- return
- }
-
- c = y
- for i, xi := range x[:len(z)] {
- zi := xi - c
- z[i] = zi
- c = (zi &^ xi) >> (_W - 1)
- }
- return
-}
-
-func shlVU_g(z, x []Word, s uint) (c Word) {
- if n := len(z); n > 0 {
- ŝ := _W - s
- w1 := x[n-1]
- c = w1 >> ŝ
- for i := n - 1; i > 0; i-- {
- w := w1
- w1 = x[i-1]
- z[i] = w<<s | w1>>ŝ
- }
- z[0] = w1 << s
- }
- return
-}
-
-func shrVU_g(z, x []Word, s uint) (c Word) {
- if n := len(z); n > 0 {
- ŝ := _W - s
- w1 := x[0]
- c = w1 << ŝ
- for i := 0; i < n-1; i++ {
- w := w1
- w1 = x[i+1]
- z[i] = w>>s | w1<<ŝ
- }
- z[n-1] = w1 >> s
- }
- return
-}
-
-func mulAddVWW_g(z, x []Word, y, r Word) (c Word) {
- c = r
- for i := range z {
- c, z[i] = mulAddWWW_g(x[i], y, c)
- }
- return
-}
-
-// TODO(gri) Remove use of addWW_g here and then we can remove addWW_g and subWW_g.
-func addMulVVW_g(z, x []Word, y Word) (c Word) {
- for i := range z {
- z1, z0 := mulAddWWW_g(x[i], y, z[i])
- c, z[i] = addWW_g(z0, c, 0)
- c += z1
- }
- return
-}
-
-func divWVW_g(z []Word, xn Word, x []Word, y Word) (r Word) {
- r = xn
- for i := len(z) - 1; i >= 0; i-- {
- z[i], r = divWW_g(r, x[i], y)
- }
- return
-}
diff --git a/src/cmd/compile/internal/big/arith_decl.go b/src/cmd/compile/internal/big/arith_decl.go
deleted file mode 100644
index d60b7f9..0000000
--- a/src/cmd/compile/internal/big/arith_decl.go
+++ /dev/null
@@ -1,53 +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.
-
-package big
-
-func mulWW(x, y Word) (z1, z0 Word) {
- return mulWW_g(x, y)
-}
-
-func divWW(x1, x0, y Word) (q, r Word) {
- return divWW_g(x1, x0, y)
-}
-
-func addVV(z, x, y []Word) (c Word) {
- return addVV_g(z, x, y)
-}
-
-func subVV(z, x, y []Word) (c Word) {
- return subVV_g(z, x, y)
-}
-
-func addVW(z, x []Word, y Word) (c Word) {
- return addVW_g(z, x, y)
-}
-
-func subVW(z, x []Word, y Word) (c Word) {
- return subVW_g(z, x, y)
-}
-
-func shlVU(z, x []Word, s uint) (c Word) {
- return shlVU_g(z, x, s)
-}
-
-func shrVU(z, x []Word, s uint) (c Word) {
- return shrVU_g(z, x, s)
-}
-
-func mulAddVWW(z, x []Word, y, r Word) (c Word) {
- return mulAddVWW_g(z, x, y, r)
-}
-
-func addMulVVW(z, x []Word, y Word) (c Word) {
- return addMulVVW_g(z, x, y)
-}
-
-func divWVW(z []Word, xn Word, x []Word, y Word) (r Word) {
- return divWVW_g(z, xn, x, y)
-}
-
-func bitLen(x Word) (n int) {
- return bitLen_g(x)
-}
diff --git a/src/cmd/compile/internal/big/arith_test.go b/src/cmd/compile/internal/big/arith_test.go
deleted file mode 100644
index 75862b4..0000000
--- a/src/cmd/compile/internal/big/arith_test.go
+++ /dev/null
@@ -1,413 +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 big
-
-import (
- "fmt"
- "math/rand"
- "testing"
-)
-
-type funWW func(x, y, c Word) (z1, z0 Word)
-type argWW struct {
- x, y, c, z1, z0 Word
-}
-
-var sumWW = []argWW{
- {0, 0, 0, 0, 0},
- {0, 1, 0, 0, 1},
- {0, 0, 1, 0, 1},
- {0, 1, 1, 0, 2},
- {12345, 67890, 0, 0, 80235},
- {12345, 67890, 1, 0, 80236},
- {_M, 1, 0, 1, 0},
- {_M, 0, 1, 1, 0},
- {_M, 1, 1, 1, 1},
- {_M, _M, 0, 1, _M - 1},
- {_M, _M, 1, 1, _M},
-}
-
-func testFunWW(t *testing.T, msg string, f funWW, a argWW) {
- z1, z0 := f(a.x, a.y, a.c)
- if z1 != a.z1 || z0 != a.z0 {
- t.Errorf("%s%+v\n\tgot z1:z0 = %#x:%#x; want %#x:%#x", msg, a, z1, z0, a.z1, a.z0)
- }
-}
-
-func TestFunWW(t *testing.T) {
- for _, a := range sumWW {
- arg := a
- testFunWW(t, "addWW_g", addWW_g, arg)
-
- arg = argWW{a.y, a.x, a.c, a.z1, a.z0}
- testFunWW(t, "addWW_g symmetric", addWW_g, arg)
-
- arg = argWW{a.z0, a.x, a.c, a.z1, a.y}
- testFunWW(t, "subWW_g", subWW_g, arg)
-
- arg = argWW{a.z0, a.y, a.c, a.z1, a.x}
- testFunWW(t, "subWW_g symmetric", subWW_g, arg)
- }
-}
-
-type funVV func(z, x, y []Word) (c Word)
-type argVV struct {
- z, x, y nat
- c Word
-}
-
-var sumVV = []argVV{
- {},
- {nat{0}, nat{0}, nat{0}, 0},
- {nat{1}, nat{1}, nat{0}, 0},
- {nat{0}, nat{_M}, nat{1}, 1},
- {nat{80235}, nat{12345}, nat{67890}, 0},
- {nat{_M - 1}, nat{_M}, nat{_M}, 1},
- {nat{0, 0, 0, 0}, nat{_M, _M, _M, _M}, nat{1, 0, 0, 0}, 1},
- {nat{0, 0, 0, _M}, nat{_M, _M, _M, _M - 1}, nat{1, 0, 0, 0}, 0},
- {nat{0, 0, 0, 0}, nat{_M, 0, _M, 0}, nat{1, _M, 0, _M}, 1},
-}
-
-func testFunVV(t *testing.T, msg string, f funVV, a argVV) {
- z := make(nat, len(a.z))
- c := f(z, a.x, a.y)
- for i, zi := range z {
- if zi != a.z[i] {
- t.Errorf("%s%+v\n\tgot z[%d] = %#x; want %#x", msg, a, i, zi, a.z[i])
- break
- }
- }
- if c != a.c {
- t.Errorf("%s%+v\n\tgot c = %#x; want %#x", msg, a, c, a.c)
- }
-}
-
-func TestFunVV(t *testing.T) {
- for _, a := range sumVV {
- arg := a
- testFunVV(t, "addVV_g", addVV_g, arg)
- testFunVV(t, "addVV", addVV, arg)
-
- arg = argVV{a.z, a.y, a.x, a.c}
- testFunVV(t, "addVV_g symmetric", addVV_g, arg)
- testFunVV(t, "addVV symmetric", addVV, arg)
-
- arg = argVV{a.x, a.z, a.y, a.c}
- testFunVV(t, "subVV_g", subVV_g, arg)
- testFunVV(t, "subVV", subVV, arg)
-
- arg = argVV{a.y, a.z, a.x, a.c}
- testFunVV(t, "subVV_g symmetric", subVV_g, arg)
- testFunVV(t, "subVV symmetric", subVV, arg)
- }
-}
-
-// Always the same seed for reproducible results.
-var rnd = rand.New(rand.NewSource(0))
-
-func rndW() Word {
- return Word(rnd.Int63()<<1 | rnd.Int63n(2))
-}
-
-func rndV(n int) []Word {
- v := make([]Word, n)
- for i := range v {
- v[i] = rndW()
- }
- return v
-}
-
-var benchSizes = []int{1, 2, 3, 4, 5, 1e1, 1e2, 1e3, 1e4, 1e5}
-
-func BenchmarkAddVV(b *testing.B) {
- for _, n := range benchSizes {
- 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++ {
- addVV(z, x, y)
- }
- })
- }
-}
-
-type funVW func(z, x []Word, y Word) (c Word)
-type argVW struct {
- z, x nat
- y Word
- c Word
-}
-
-var sumVW = []argVW{
- {},
- {nil, nil, 2, 2},
- {nat{0}, nat{0}, 0, 0},
- {nat{1}, nat{0}, 1, 0},
- {nat{1}, nat{1}, 0, 0},
- {nat{0}, nat{_M}, 1, 1},
- {nat{0, 0, 0, 0}, nat{_M, _M, _M, _M}, 1, 1},
- {nat{585}, nat{314}, 271, 0},
-}
-
-var lshVW = []argVW{
- {},
- {nat{0}, nat{0}, 0, 0},
- {nat{0}, nat{0}, 1, 0},
- {nat{0}, nat{0}, 20, 0},
-
- {nat{_M}, nat{_M}, 0, 0},
- {nat{_M << 1 & _M}, nat{_M}, 1, 1},
- {nat{_M << 20 & _M}, nat{_M}, 20, _M >> (_W - 20)},
-
- {nat{_M, _M, _M}, nat{_M, _M, _M}, 0, 0},
- {nat{_M << 1 & _M, _M, _M}, nat{_M, _M, _M}, 1, 1},
- {nat{_M << 20 & _M, _M, _M}, nat{_M, _M, _M}, 20, _M >> (_W - 20)},
-}
-
-var rshVW = []argVW{
- {},
- {nat{0}, nat{0}, 0, 0},
- {nat{0}, nat{0}, 1, 0},
- {nat{0}, nat{0}, 20, 0},
-
- {nat{_M}, nat{_M}, 0, 0},
- {nat{_M >> 1}, nat{_M}, 1, _M << (_W - 1) & _M},
- {nat{_M >> 20}, nat{_M}, 20, _M << (_W - 20) & _M},
-
- {nat{_M, _M, _M}, nat{_M, _M, _M}, 0, 0},
- {nat{_M, _M, _M >> 1}, nat{_M, _M, _M}, 1, _M << (_W - 1) & _M},
- {nat{_M, _M, _M >> 20}, nat{_M, _M, _M}, 20, _M << (_W - 20) & _M},
-}
-
-func testFunVW(t *testing.T, msg string, f funVW, a argVW) {
- z := make(nat, len(a.z))
- c := f(z, a.x, a.y)
- for i, zi := range z {
- if zi != a.z[i] {
- t.Errorf("%s%+v\n\tgot z[%d] = %#x; want %#x", msg, a, i, zi, a.z[i])
- break
- }
- }
- if c != a.c {
- t.Errorf("%s%+v\n\tgot c = %#x; want %#x", msg, a, c, a.c)
- }
-}
-
-func makeFunVW(f func(z, x []Word, s uint) (c Word)) funVW {
- return func(z, x []Word, s Word) (c Word) {
- return f(z, x, uint(s))
- }
-}
-
-func TestFunVW(t *testing.T) {
- for _, a := range sumVW {
- arg := a
- testFunVW(t, "addVW_g", addVW_g, arg)
- testFunVW(t, "addVW", addVW, arg)
-
- arg = argVW{a.x, a.z, a.y, a.c}
- testFunVW(t, "subVW_g", subVW_g, arg)
- testFunVW(t, "subVW", subVW, arg)
- }
-
- shlVW_g := makeFunVW(shlVU_g)
- shlVW := makeFunVW(shlVU)
- for _, a := range lshVW {
- arg := a
- testFunVW(t, "shlVU_g", shlVW_g, arg)
- testFunVW(t, "shlVU", shlVW, arg)
- }
-
- shrVW_g := makeFunVW(shrVU_g)
- shrVW := makeFunVW(shrVU)
- for _, a := range rshVW {
- arg := a
- testFunVW(t, "shrVU_g", shrVW_g, arg)
- testFunVW(t, "shrVU", shrVW, arg)
- }
-}
-
-func BenchmarkAddVW(b *testing.B) {
- for _, n := range benchSizes {
- 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++ {
- addVW(z, x, y)
- }
- })
- }
-}
-
-type funVWW func(z, x []Word, y, r Word) (c Word)
-type argVWW struct {
- z, x nat
- y, r Word
- c Word
-}
-
-var prodVWW = []argVWW{
- {},
- {nat{0}, nat{0}, 0, 0, 0},
- {nat{991}, nat{0}, 0, 991, 0},
- {nat{0}, nat{_M}, 0, 0, 0},
- {nat{991}, nat{_M}, 0, 991, 0},
- {nat{0}, nat{0}, _M, 0, 0},
- {nat{991}, nat{0}, _M, 991, 0},
- {nat{1}, nat{1}, 1, 0, 0},
- {nat{992}, nat{1}, 1, 991, 0},
- {nat{22793}, nat{991}, 23, 0, 0},
- {nat{22800}, nat{991}, 23, 7, 0},
- {nat{0, 0, 0, 22793}, nat{0, 0, 0, 991}, 23, 0, 0},
- {nat{7, 0, 0, 22793}, nat{0, 0, 0, 991}, 23, 7, 0},
- {nat{0, 0, 0, 0}, nat{7893475, 7395495, 798547395, 68943}, 0, 0, 0},
- {nat{991, 0, 0, 0}, nat{7893475, 7395495, 798547395, 68943}, 0, 991, 0},
- {nat{0, 0, 0, 0}, nat{0, 0, 0, 0}, 894375984, 0, 0},
- {nat{991, 0, 0, 0}, nat{0, 0, 0, 0}, 894375984, 991, 0},
- {nat{_M << 1 & _M}, nat{_M}, 1 << 1, 0, _M >> (_W - 1)},
- {nat{_M<<1&_M + 1}, nat{_M}, 1 << 1, 1, _M >> (_W - 1)},
- {nat{_M << 7 & _M}, nat{_M}, 1 << 7, 0, _M >> (_W - 7)},
- {nat{_M<<7&_M + 1<<6}, nat{_M}, 1 << 7, 1 << 6, _M >> (_W - 7)},
- {nat{_M << 7 & _M, _M, _M, _M}, nat{_M, _M, _M, _M}, 1 << 7, 0, _M >> (_W - 7)},
- {nat{_M<<7&_M + 1<<6, _M, _M, _M}, nat{_M, _M, _M, _M}, 1 << 7, 1 << 6, _M >> (_W - 7)},
-}
-
-func testFunVWW(t *testing.T, msg string, f funVWW, a argVWW) {
- z := make(nat, len(a.z))
- c := f(z, a.x, a.y, a.r)
- for i, zi := range z {
- if zi != a.z[i] {
- t.Errorf("%s%+v\n\tgot z[%d] = %#x; want %#x", msg, a, i, zi, a.z[i])
- break
- }
- }
- if c != a.c {
- t.Errorf("%s%+v\n\tgot c = %#x; want %#x", msg, a, c, a.c)
- }
-}
-
-// TODO(gri) mulAddVWW and divWVW are symmetric operations but
-// their signature is not symmetric. Try to unify.
-
-type funWVW func(z []Word, xn Word, x []Word, y Word) (r Word)
-type argWVW struct {
- z nat
- xn Word
- x nat
- y Word
- r Word
-}
-
-func testFunWVW(t *testing.T, msg string, f funWVW, a argWVW) {
- z := make(nat, len(a.z))
- r := f(z, a.xn, a.x, a.y)
- for i, zi := range z {
- if zi != a.z[i] {
- t.Errorf("%s%+v\n\tgot z[%d] = %#x; want %#x", msg, a, i, zi, a.z[i])
- break
- }
- }
- if r != a.r {
- t.Errorf("%s%+v\n\tgot r = %#x; want %#x", msg, a, r, a.r)
- }
-}
-
-func TestFunVWW(t *testing.T) {
- for _, a := range prodVWW {
- arg := a
- testFunVWW(t, "mulAddVWW_g", mulAddVWW_g, arg)
- testFunVWW(t, "mulAddVWW", mulAddVWW, arg)
-
- if a.y != 0 && a.r < a.y {
- arg := argWVW{a.x, a.c, a.z, a.y, a.r}
- testFunWVW(t, "divWVW_g", divWVW_g, arg)
- testFunWVW(t, "divWVW", divWVW, arg)
- }
- }
-}
-
-var mulWWTests = []struct {
- x, y Word
- q, r Word
-}{
- {_M, _M, _M - 1, 1},
- // 32 bit only: {0xc47dfa8c, 50911, 0x98a4, 0x998587f4},
-}
-
-func TestMulWW(t *testing.T) {
- for i, test := range mulWWTests {
- q, r := mulWW_g(test.x, test.y)
- if q != test.q || r != test.r {
- t.Errorf("#%d got (%x, %x) want (%x, %x)", i, q, r, test.q, test.r)
- }
- }
-}
-
-var mulAddWWWTests = []struct {
- x, y, c Word
- q, r Word
-}{
- // TODO(agl): These will only work on 64-bit platforms.
- // {15064310297182388543, 0xe7df04d2d35d5d80, 13537600649892366549, 13644450054494335067, 10832252001440893781},
- // {15064310297182388543, 0xdab2f18048baa68d, 13644450054494335067, 12869334219691522700, 14233854684711418382},
- {_M, _M, 0, _M - 1, 1},
- {_M, _M, _M, _M, 0},
-}
-
-func TestMulAddWWW(t *testing.T) {
- for i, test := range mulAddWWWTests {
- q, r := mulAddWWW_g(test.x, test.y, test.c)
- if q != test.q || r != test.r {
- t.Errorf("#%d got (%x, %x) want (%x, %x)", i, q, r, test.q, test.r)
- }
- }
-}
-
-func BenchmarkAddMulVVW(b *testing.B) {
- for _, n := range benchSizes {
- x := rndV(n)
- y := rndW()
- 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++ {
- addMulVVW(z, x, y)
- }
- })
- }
-}
-
-func testWordBitLen(t *testing.T, fname string, f func(Word) int) {
- for i := 0; i <= _W; i++ {
- x := Word(1) << uint(i-1) // i == 0 => x == 0
- n := f(x)
- if n != i {
- t.Errorf("got %d; want %d for %s(%#x)", n, i, fname, x)
- }
- }
-}
-
-func TestWordBitLen(t *testing.T) {
- testWordBitLen(t, "bitLen", bitLen)
- testWordBitLen(t, "bitLen_g", bitLen_g)
-}
-
-// runs b.N iterations of bitLen called on a Word containing (1 << nbits)-1.
-func BenchmarkBitLen(b *testing.B) {
- // Individual bitLen tests. Numbers chosen to examine both sides
- // of powers-of-two boundaries.
- for _, nbits := range []uint{0, 1, 2, 3, 4, 5, 8, 9, 16, 17, 31} {
- testword := Word((uint64(1) << nbits) - 1)
- b.Run(fmt.Sprint(nbits), func(b *testing.B) {
- for i := 0; i < b.N; i++ {
- bitLen(testword)
- }
- })
- }
-}
diff --git a/src/cmd/compile/internal/big/bits_test.go b/src/cmd/compile/internal/big/bits_test.go
deleted file mode 100644
index 985b60b..0000000
--- a/src/cmd/compile/internal/big/bits_test.go
+++ /dev/null
@@ -1,224 +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.
-
-// This file implements the Bits type used for testing Float operations
-// via an independent (albeit slower) representations for floating-point
-// numbers.
-
-package big
-
-import (
- "fmt"
- "sort"
- "testing"
-)
-
-// A Bits value b represents a finite floating-point number x of the form
-//
-// x = 2**b[0] + 2**b[1] + ... 2**b[len(b)-1]
-//
-// The order of slice elements is not significant. Negative elements may be
-// used to form fractions. A Bits value is normalized if each b[i] occurs at
-// most once. For instance Bits{0, 0, 1} is not normalized but represents the
-// same floating-point number as Bits{2}, which is normalized. The zero (nil)
-// value of Bits is a ready to use Bits value and represents the value 0.
-type Bits []int
-
-func (x Bits) add(y Bits) Bits {
- return append(x, y...)
-}
-
-func (x Bits) mul(y Bits) Bits {
- var p Bits
- for _, x := range x {
- for _, y := range y {
- p = append(p, x+y)
- }
- }
- return p
-}
-
-func TestMulBits(t *testing.T) {
- for _, test := range []struct {
- x, y, want Bits
- }{
- {nil, nil, nil},
- {Bits{}, Bits{}, nil},
- {Bits{0}, Bits{0}, Bits{0}},
- {Bits{0}, Bits{1}, Bits{1}},
- {Bits{1}, Bits{1, 2, 3}, Bits{2, 3, 4}},
- {Bits{-1}, Bits{1}, Bits{0}},
- {Bits{-10, -1, 0, 1, 10}, Bits{1, 2, 3}, Bits{-9, -8, -7, 0, 1, 2, 1, 2, 3, 2, 3, 4, 11, 12, 13}},
- } {
- got := fmt.Sprintf("%v", test.x.mul(test.y))
- want := fmt.Sprintf("%v", test.want)
- if got != want {
- t.Errorf("%v * %v = %s; want %s", test.x, test.y, got, want)
- }
-
- }
-}
-
-// norm returns the normalized bits for x: It removes multiple equal entries
-// by treating them as an addition (e.g., Bits{5, 5} => Bits{6}), and it sorts
-// the result list for reproducible results.
-func (x Bits) norm() Bits {
- m := make(map[int]bool)
- for _, b := range x {
- for m[b] {
- m[b] = false
- b++
- }
- m[b] = true
- }
- var z Bits
- for b, set := range m {
- if set {
- z = append(z, b)
- }
- }
- sort.Ints([]int(z))
- return z
-}
-
-func TestNormBits(t *testing.T) {
- for _, test := range []struct {
- x, want Bits
- }{
- {nil, nil},
- {Bits{}, Bits{}},
- {Bits{0}, Bits{0}},
- {Bits{0, 0}, Bits{1}},
- {Bits{3, 1, 1}, Bits{2, 3}},
- {Bits{10, 9, 8, 7, 6, 6}, Bits{11}},
- } {
- got := fmt.Sprintf("%v", test.x.norm())
- want := fmt.Sprintf("%v", test.want)
- if got != want {
- t.Errorf("normBits(%v) = %s; want %s", test.x, got, want)
- }
-
- }
-}
-
-// round returns the Float value corresponding to x after rounding x
-// to prec bits according to mode.
-func (x Bits) round(prec uint, mode RoundingMode) *Float {
- x = x.norm()
-
- // determine range
- var min, max int
- for i, b := range x {
- if i == 0 || b < min {
- min = b
- }
- if i == 0 || b > max {
- max = b
- }
- }
- prec0 := uint(max + 1 - min)
- if prec >= prec0 {
- return x.Float()
- }
- // prec < prec0
-
- // determine bit 0, rounding, and sticky bit, and result bits z
- var bit0, rbit, sbit uint
- var z Bits
- r := max - int(prec)
- for _, b := range x {
- switch {
- case b == r:
- rbit = 1
- case b < r:
- sbit = 1
- default:
- // b > r
- if b == r+1 {
- bit0 = 1
- }
- z = append(z, b)
- }
- }
-
- // round
- f := z.Float() // rounded to zero
- if mode == ToNearestAway {
- panic("not yet implemented")
- }
- if mode == ToNearestEven && rbit == 1 && (sbit == 1 || sbit == 0 && bit0 != 0) || mode == AwayFromZero {
- // round away from zero
- f.SetMode(ToZero).SetPrec(prec)
- f.Add(f, Bits{int(r) + 1}.Float())
- }
- return f
-}
-
-// Float returns the *Float z of the smallest possible precision such that
-// z = sum(2**bits[i]), with i = range bits. If multiple bits[i] are equal,
-// they are added: Bits{0, 1, 0}.Float() == 2**0 + 2**1 + 2**0 = 4.
-func (bits Bits) Float() *Float {
- // handle 0
- if len(bits) == 0 {
- return new(Float)
- }
- // len(bits) > 0
-
- // determine lsb exponent
- var min int
- for i, b := range bits {
- if i == 0 || b < min {
- min = b
- }
- }
-
- // create bit pattern
- x := NewInt(0)
- for _, b := range bits {
- badj := b - min
- // propagate carry if necessary
- for x.Bit(badj) != 0 {
- x.SetBit(x, badj, 0)
- badj++
- }
- x.SetBit(x, badj, 1)
- }
-
- // create corresponding float
- z := new(Float).SetInt(x) // normalized
- if e := int64(z.exp) + int64(min); MinExp <= e && e <= MaxExp {
- z.exp = int32(e)
- } else {
- // this should never happen for our test cases
- panic("exponent out of range")
- }
- return z
-}
-
-func TestFromBits(t *testing.T) {
- for _, test := range []struct {
- bits Bits
- want string
- }{
- // all different bit numbers
- {nil, "0"},
- {Bits{0}, "0x.8p+1"},
- {Bits{1}, "0x.8p+2"},
- {Bits{-1}, "0x.8p+0"},
- {Bits{63}, "0x.8p+64"},
- {Bits{33, -30}, "0x.8000000000000001p+34"},
- {Bits{255, 0}, "0x.8000000000000000000000000000000000000000000000000000000000000001p+256"},
-
- // multiple equal bit numbers
- {Bits{0, 0}, "0x.8p+2"},
- {Bits{0, 0, 0, 0}, "0x.8p+3"},
- {Bits{0, 1, 0}, "0x.8p+3"},
- {append(Bits{2, 1, 0} /* 7 */, Bits{3, 1} /* 10 */ ...), "0x.88p+5" /* 17 */},
- } {
- f := test.bits.Float()
- if got := f.Text('p', 0); got != test.want {
- t.Errorf("setBits(%v) = %s; want %s", test.bits, got, test.want)
- }
- }
-}
diff --git a/src/cmd/compile/internal/big/calibrate_test.go b/src/cmd/compile/internal/big/calibrate_test.go
deleted file mode 100644
index f69ffbf..0000000
--- a/src/cmd/compile/internal/big/calibrate_test.go
+++ /dev/null
@@ -1,88 +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.
-
-// This file prints execution times for the Mul benchmark
-// given different Karatsuba thresholds. The result may be
-// used to manually fine-tune the threshold constant. The
-// results are somewhat fragile; use repeated runs to get
-// a clear picture.
-
-// Usage: go test -run=TestCalibrate -calibrate
-
-package big
-
-import (
- "flag"
- "fmt"
- "testing"
- "time"
-)
-
-var calibrate = flag.Bool("calibrate", false, "run calibration test")
-
-func karatsubaLoad(b *testing.B) {
- BenchmarkMul(b)
-}
-
-// measureKaratsuba returns the time to run a Karatsuba-relevant benchmark
-// given Karatsuba threshold th.
-func measureKaratsuba(th int) time.Duration {
- th, karatsubaThreshold = karatsubaThreshold, th
- res := testing.Benchmark(karatsubaLoad)
- karatsubaThreshold = th
- return time.Duration(res.NsPerOp())
-}
-
-func computeThresholds() {
- fmt.Printf("Multiplication times for varying Karatsuba thresholds\n")
- fmt.Printf("(run repeatedly for good results)\n")
-
- // determine Tk, the work load execution time using basic multiplication
- Tb := measureKaratsuba(1e9) // th == 1e9 => Karatsuba multiplication disabled
- fmt.Printf("Tb = %10s\n", Tb)
-
- // thresholds
- th := 4
- th1 := -1
- th2 := -1
-
- var deltaOld time.Duration
- for count := -1; count != 0 && th < 128; count-- {
- // determine Tk, the work load execution time using Karatsuba multiplication
- Tk := measureKaratsuba(th)
-
- // improvement over Tb
- delta := (Tb - Tk) * 100 / Tb
-
- fmt.Printf("th = %3d Tk = %10s %4d%%", th, Tk, delta)
-
- // determine break-even point
- if Tk < Tb && th1 < 0 {
- th1 = th
- fmt.Print(" break-even point")
- }
-
- // determine diminishing return
- if 0 < delta && delta < deltaOld && th2 < 0 {
- th2 = th
- fmt.Print(" diminishing return")
- }
- deltaOld = delta
-
- fmt.Println()
-
- // trigger counter
- if th1 >= 0 && th2 >= 0 && count < 0 {
- count = 10 // this many extra measurements after we got both thresholds
- }
-
- th++
- }
-}
-
-func TestCalibrate(t *testing.T) {
- if *calibrate {
- computeThresholds()
- }
-}
diff --git a/src/cmd/compile/internal/big/decimal.go b/src/cmd/compile/internal/big/decimal.go
deleted file mode 100644
index 2c0c9da..0000000
--- a/src/cmd/compile/internal/big/decimal.go
+++ /dev/null
@@ -1,266 +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.
-
-// This file implements multi-precision decimal numbers.
-// The implementation is for float to decimal conversion only;
-// not general purpose use.
-// The only operations are precise conversion from binary to
-// decimal and rounding.
-//
-// The key observation and some code (shr) is borrowed from
-// strconv/decimal.go: conversion of binary fractional values can be done
-// precisely in multi-precision decimal because 2 divides 10 (required for
-// >> of mantissa); but conversion of decimal floating-point values cannot
-// be done precisely in binary representation.
-//
-// In contrast to strconv/decimal.go, only right shift is implemented in
-// decimal format - left shift can be done precisely in binary format.
-
-package big
-
-// A decimal represents an unsigned floating-point number in decimal representation.
-// The value of a non-zero decimal d is d.mant * 10**d.exp with 0.5 <= d.mant < 1,
-// with the most-significant mantissa digit at index 0. For the zero decimal, the
-// mantissa length and exponent are 0.
-// The zero value for decimal represents a ready-to-use 0.0.
-type decimal struct {
- mant []byte // mantissa ASCII digits, big-endian
- exp int // exponent
-}
-
-// at returns the i'th mantissa digit, starting with the most significant digit at 0.
-func (d *decimal) at(i int) byte {
- if 0 <= i && i < len(d.mant) {
- return d.mant[i]
- }
- return '0'
-}
-
-// Maximum shift amount that can be done in one pass without overflow.
-// A Word has _W bits and (1<<maxShift - 1)*10 + 9 must fit into Word.
-const maxShift = _W - 4
-
-// TODO(gri) Since we know the desired decimal precision when converting
-// a floating-point number, we may be able to limit the number of decimal
-// digits that need to be computed by init by providing an additional
-// precision argument and keeping track of when a number was truncated early
-// (equivalent of "sticky bit" in binary rounding).
-
-// TODO(gri) Along the same lines, enforce some limit to shift magnitudes
-// to avoid "infinitely" long running conversions (until we run out of space).
-
-// Init initializes x to the decimal representation of m << shift (for
-// shift >= 0), or m >> -shift (for shift < 0).
-func (x *decimal) init(m nat, shift int) {
- // special case 0
- if len(m) == 0 {
- x.mant = x.mant[:0]
- x.exp = 0
- return
- }
-
- // Optimization: If we need to shift right, first remove any trailing
- // zero bits from m to reduce shift amount that needs to be done in
- // decimal format (since that is likely slower).
- if shift < 0 {
- ntz := m.trailingZeroBits()
- s := uint(-shift)
- if s >= ntz {
- s = ntz // shift at most ntz bits
- }
- m = nat(nil).shr(m, s)
- shift += int(s)
- }
-
- // Do any shift left in binary representation.
- if shift > 0 {
- m = nat(nil).shl(m, uint(shift))
- shift = 0
- }
-
- // Convert mantissa into decimal representation.
- s := m.utoa(10)
- n := len(s)
- x.exp = n
- // Trim trailing zeros; instead the exponent is tracking
- // the decimal point independent of the number of digits.
- for n > 0 && s[n-1] == '0' {
- n--
- }
- x.mant = append(x.mant[:0], s[:n]...)
-
- // Do any (remaining) shift right in decimal representation.
- if shift < 0 {
- for shift < -maxShift {
- shr(x, maxShift)
- shift += maxShift
- }
- shr(x, uint(-shift))
- }
-}
-
-// shr implements x >> s, for s <= maxShift.
-func shr(x *decimal, s uint) {
- // Division by 1<<s using shift-and-subtract algorithm.
-
- // pick up enough leading digits to cover first shift
- r := 0 // read index
- var n Word
- for n>>s == 0 && r < len(x.mant) {
- ch := Word(x.mant[r])
- r++
- n = n*10 + ch - '0'
- }
- if n == 0 {
- // x == 0; shouldn't get here, but handle anyway
- x.mant = x.mant[:0]
- return
- }
- for n>>s == 0 {
- r++
- n *= 10
- }
- x.exp += 1 - r
-
- // read a digit, write a digit
- w := 0 // write index
- for r < len(x.mant) {
- ch := Word(x.mant[r])
- r++
- d := n >> s
- n -= d << s
- x.mant[w] = byte(d + '0')
- w++
- n = n*10 + ch - '0'
- }
-
- // write extra digits that still fit
- for n > 0 && w < len(x.mant) {
- d := n >> s
- n -= d << s
- x.mant[w] = byte(d + '0')
- w++
- n = n * 10
- }
- x.mant = x.mant[:w] // the number may be shorter (e.g. 1024 >> 10)
-
- // append additional digits that didn't fit
- for n > 0 {
- d := n >> s
- n -= d << s
- x.mant = append(x.mant, byte(d+'0'))
- n = n * 10
- }
-
- trim(x)
-}
-
-func (x *decimal) String() string {
- if len(x.mant) == 0 {
- return "0"
- }
-
- var buf []byte
- switch {
- case x.exp <= 0:
- // 0.00ddd
- buf = append(buf, "0."...)
- buf = appendZeros(buf, -x.exp)
- buf = append(buf, x.mant...)
-
- case /* 0 < */ x.exp < len(x.mant):
- // dd.ddd
- buf = append(buf, x.mant[:x.exp]...)
- buf = append(buf, '.')
- buf = append(buf, x.mant[x.exp:]...)
-
- default: // len(x.mant) <= x.exp
- // ddd00
- buf = append(buf, x.mant...)
- buf = appendZeros(buf, x.exp-len(x.mant))
- }
-
- return string(buf)
-}
-
-// appendZeros appends n 0 digits to buf and returns buf.
-func appendZeros(buf []byte, n int) []byte {
- for ; n > 0; n-- {
- buf = append(buf, '0')
- }
- return buf
-}
-
-// shouldRoundUp reports if x should be rounded up
-// if shortened to n digits. n must be a valid index
-// for x.mant.
-func shouldRoundUp(x *decimal, n int) bool {
- if x.mant[n] == '5' && n+1 == len(x.mant) {
- // exactly halfway - round to even
- return n > 0 && (x.mant[n-1]-'0')&1 != 0
- }
- // not halfway - digit tells all (x.mant has no trailing zeros)
- return x.mant[n] >= '5'
-}
-
-// round sets x to (at most) n mantissa digits by rounding it
-// to the nearest even value with n (or fever) mantissa digits.
-// If n < 0, x remains unchanged.
-func (x *decimal) round(n int) {
- if n < 0 || n >= len(x.mant) {
- return // nothing to do
- }
-
- if shouldRoundUp(x, n) {
- x.roundUp(n)
- } else {
- x.roundDown(n)
- }
-}
-
-func (x *decimal) roundUp(n int) {
- if n < 0 || n >= len(x.mant) {
- return // nothing to do
- }
- // 0 <= n < len(x.mant)
-
- // find first digit < '9'
- for n > 0 && x.mant[n-1] >= '9' {
- n--
- }
-
- if n == 0 {
- // all digits are '9's => round up to '1' and update exponent
- x.mant[0] = '1' // ok since len(x.mant) > n
- x.mant = x.mant[:1]
- x.exp++
- return
- }
-
- // n > 0 && x.mant[n-1] < '9'
- x.mant[n-1]++
- x.mant = x.mant[:n]
- // x already trimmed
-}
-
-func (x *decimal) roundDown(n int) {
- if n < 0 || n >= len(x.mant) {
- return // nothing to do
- }
- x.mant = x.mant[:n]
- trim(x)
-}
-
-// trim cuts off any trailing zeros from x's mantissa;
-// they are meaningless for the value of x.
-func trim(x *decimal) {
- i := len(x.mant)
- for i > 0 && x.mant[i-1] == '0' {
- i--
- }
- x.mant = x.mant[:i]
- if i == 0 {
- x.exp = 0
- }
-}
diff --git a/src/cmd/compile/internal/big/decimal_test.go b/src/cmd/compile/internal/big/decimal_test.go
deleted file mode 100644
index 13452f8..0000000
--- a/src/cmd/compile/internal/big/decimal_test.go
+++ /dev/null
@@ -1,118 +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.
-
-package big
-
-import "testing"
-
-func TestDecimalString(t *testing.T) {
- for _, test := range []struct {
- x decimal
- want string
- }{
- {want: "0"},
- {decimal{nil, 1000}, "0"}, // exponent of 0 is ignored
- {decimal{[]byte("12345"), 0}, "0.12345"},
- {decimal{[]byte("12345"), -3}, "0.00012345"},
- {decimal{[]byte("12345"), +3}, "123.45"},
- {decimal{[]byte("12345"), +10}, "1234500000"},
- } {
- if got := test.x.String(); got != test.want {
- t.Errorf("%v == %s; want %s", test.x, got, test.want)
- }
- }
-}
-
-func TestDecimalInit(t *testing.T) {
- for _, test := range []struct {
- x Word
- shift int
- want string
- }{
- {0, 0, "0"},
- {0, -100, "0"},
- {0, 100, "0"},
- {1, 0, "1"},
- {1, 10, "1024"},
- {1, 100, "1267650600228229401496703205376"},
- {1, -100, "0.0000000000000000000000000000007888609052210118054117285652827862296732064351090230047702789306640625"},
- {12345678, 8, "3160493568"},
- {12345678, -8, "48225.3046875"},
- {195312, 9, "99999744"},
- {1953125, 9, "1000000000"},
- } {
- var d decimal
- d.init(nat{test.x}.norm(), test.shift)
- if got := d.String(); got != test.want {
- t.Errorf("%d << %d == %s; want %s", test.x, test.shift, got, test.want)
- }
- }
-}
-
-func TestDecimalRounding(t *testing.T) {
- for _, test := range []struct {
- x uint64
- n int
- down, even, up string
- }{
- {0, 0, "0", "0", "0"},
- {0, 1, "0", "0", "0"},
-
- {1, 0, "0", "0", "10"},
- {5, 0, "0", "0", "10"},
- {9, 0, "0", "10", "10"},
-
- {15, 1, "10", "20", "20"},
- {45, 1, "40", "40", "50"},
- {95, 1, "90", "100", "100"},
-
- {12344999, 4, "12340000", "12340000", "12350000"},
- {12345000, 4, "12340000", "12340000", "12350000"},
- {12345001, 4, "12340000", "12350000", "12350000"},
- {23454999, 4, "23450000", "23450000", "23460000"},
- {23455000, 4, "23450000", "23460000", "23460000"},
- {23455001, 4, "23450000", "23460000", "23460000"},
-
- {99994999, 4, "99990000", "99990000", "100000000"},
- {99995000, 4, "99990000", "100000000", "100000000"},
- {99999999, 4, "99990000", "100000000", "100000000"},
-
- {12994999, 4, "12990000", "12990000", "13000000"},
- {12995000, 4, "12990000", "13000000", "13000000"},
- {12999999, 4, "12990000", "13000000", "13000000"},
- } {
- x := nat(nil).setUint64(test.x)
-
- var d decimal
- d.init(x, 0)
- d.roundDown(test.n)
- if got := d.String(); got != test.down {
- t.Errorf("roundDown(%d, %d) = %s; want %s", test.x, test.n, got, test.down)
- }
-
- d.init(x, 0)
- d.round(test.n)
- if got := d.String(); got != test.even {
- t.Errorf("round(%d, %d) = %s; want %s", test.x, test.n, got, test.even)
- }
-
- d.init(x, 0)
- d.roundUp(test.n)
- if got := d.String(); got != test.up {
- t.Errorf("roundUp(%d, %d) = %s; want %s", test.x, test.n, got, test.up)
- }
- }
-}
-
-var sink string
-
-func BenchmarkDecimalConversion(b *testing.B) {
- for i := 0; i < b.N; i++ {
- for shift := -100; shift <= +100; shift++ {
- var d decimal
- d.init(natOne, shift)
- sink = d.String()
- }
- }
-}
diff --git a/src/cmd/compile/internal/big/doc.go b/src/cmd/compile/internal/big/doc.go
deleted file mode 100644
index a3c2375..0000000
--- a/src/cmd/compile/internal/big/doc.go
+++ /dev/null
@@ -1,99 +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 big implements arbitrary-precision arithmetic (big numbers).
-The following numeric types are supported:
-
- Int signed integers
- Rat rational numbers
- Float floating-point numbers
-
-The zero value for an Int, Rat, or Float correspond to 0. Thus, new
-values can be declared in the usual ways and denote 0 without further
-initialization:
-
- var x Int // &x is an *Int of value 0
- var r = &Rat{} // r is a *Rat of value 0
- y := new(Float) // y is a *Float of value 0
-
-Alternatively, new values can be allocated and initialized with factory
-functions of the form:
-
- func NewT(v V) *T
-
-For instance, NewInt(x) returns an *Int set to the value of the int64
-argument x, NewRat(a, b) returns a *Rat set to the fraction a/b where
-a and b are int64 values, and NewFloat(f) returns a *Float initialized
-to the float64 argument f. More flexibility is provided with explicit
-setters, for instance:
-
- var z1 Int
- z1.SetUint64(123) // z1 := 123
- z2 := new(Rat).SetFloat64(1.2) // z2 := 6/5
- z3 := new(Float).SetInt(z1) // z3 := 123.0
-
-Setters, numeric operations and predicates are represented as methods of
-the form:
-
- func (z *T) SetV(v V) *T // z = v
- func (z *T) Unary(x *T) *T // z = unary x
- func (z *T) Binary(x, y *T) *T // z = x binary y
- func (x *T) Pred() P // p = pred(x)
-
-with T one of Int, Rat, or Float. For unary and binary operations, the
-result is the receiver (usually named z in that case; see below); if it
-is one of the operands x or y it may be safely overwritten (and its memory
-reused).
-
-Arithmetic expressions are typically written as a sequence of individual
-method calls, with each call corresponding to an operation. The receiver
-denotes the result and the method arguments are the operation's operands.
-For instance, given three *Int values a, b and c, the invocation
-
- c.Add(a, b)
-
-computes the sum a + b and stores the result in c, overwriting whatever
-value was held in c before. Unless specified otherwise, operations permit
-aliasing of parameters, so it is perfectly ok to write
-
- sum.Add(sum, x)
-
-to accumulate values x in a sum.
-
-(By always passing in a result value via the receiver, memory use can be
-much better controlled. Instead of having to allocate new memory for each
-result, an operation can reuse the space allocated for the result value,
-and overwrite that value with the new result in the process.)
-
-Notational convention: Incoming method parameters (including the receiver)
-are named consistently in the API to clarify their use. Incoming operands
-are usually named x, y, a, b, and so on, but never z. A parameter specifying
-the result is named z (typically the receiver).
-
-For instance, the arguments for (*Int).Add are named x and y, and because
-the receiver specifies the result destination, it is called z:
-
- func (z *Int) Add(x, y *Int) *Int
-
-Methods of this form typically return the incoming receiver as well, to
-enable simple call chaining.
-
-Methods which don't require a result value to be passed in (for instance,
-Int.Sign), simply return the result. In this case, the receiver is typically
-the first operand, named x:
-
- func (x *Int) Sign() int
-
-Various methods support conversions between strings and corresponding
-numeric values, and vice versa: *Int, *Rat, and *Float values implement
-the Stringer interface for a (default) string representation of the value,
-but also provide SetString methods to initialize a value from a string in
-a variety of supported formats (see the respective SetString documentation).
-
-Finally, *Int, *Rat, and *Float satisfy the fmt package's Scanner interface
-for scanning and (except for *Rat) the Formatter interface for formatted
-printing.
-*/
-package big
diff --git a/src/cmd/compile/internal/big/example_rat_test.go b/src/cmd/compile/internal/big/example_rat_test.go
deleted file mode 100644
index ef06497..0000000
--- a/src/cmd/compile/internal/big/example_rat_test.go
+++ /dev/null
@@ -1,65 +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.
-
-package big_test
-
-import (
- "cmd/compile/internal/big"
- "fmt"
-)
-
-// Use the classic continued fraction for e
-// e = [1; 0, 1, 1, 2, 1, 1, ... 2n, 1, 1, ...]
-// i.e., for the nth term, use
-// 1 if n mod 3 != 1
-// (n-1)/3 * 2 if n mod 3 == 1
-func recur(n, lim int64) *big.Rat {
- term := new(big.Rat)
- if n%3 != 1 {
- term.SetInt64(1)
- } else {
- term.SetInt64((n - 1) / 3 * 2)
- }
-
- if n > lim {
- return term
- }
-
- // Directly initialize frac as the fractional
- // inverse of the result of recur.
- frac := new(big.Rat).Inv(recur(n+1, lim))
-
- return term.Add(term, frac)
-}
-
-// This example demonstrates how to use big.Rat to compute the
-// first 15 terms in the sequence of rational convergents for
-// the constant e (base of natural logarithm).
-func Example_eConvergents() {
- for i := 1; i <= 15; i++ {
- r := recur(0, int64(i))
-
- // Print r both as a fraction and as a floating-point number.
- // Since big.Rat implements fmt.Formatter, we can use %-13s to
- // get a left-aligned string representation of the fraction.
- fmt.Printf("%-13s = %s\n", r, r.FloatString(8))
- }
-
- // Output:
- // 2/1 = 2.00000000
- // 3/1 = 3.00000000
- // 8/3 = 2.66666667
- // 11/4 = 2.75000000
- // 19/7 = 2.71428571
- // 87/32 = 2.71875000
- // 106/39 = 2.71794872
- // 193/71 = 2.71830986
- // 1264/465 = 2.71827957
- // 1457/536 = 2.71828358
- // 2721/1001 = 2.71828172
- // 23225/8544 = 2.71828184
- // 25946/9545 = 2.71828182
- // 49171/18089 = 2.71828183
- // 517656/190435 = 2.71828183
-}
diff --git a/src/cmd/compile/internal/big/example_test.go b/src/cmd/compile/internal/big/example_test.go
deleted file mode 100644
index 8a71a08..0000000
--- a/src/cmd/compile/internal/big/example_test.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2012 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 big_test
-
-import (
- "cmd/compile/internal/big"
- "fmt"
- "log"
- "math"
-)
-
-func ExampleRat_SetString() {
- r := new(big.Rat)
- r.SetString("355/113")
- fmt.Println(r.FloatString(3))
- // Output: 3.142
-}
-
-func ExampleInt_SetString() {
- i := new(big.Int)
- i.SetString("644", 8) // octal
- fmt.Println(i)
- // Output: 420
-}
-
-func ExampleRat_Scan() {
- // The Scan function is rarely used directly;
- // the fmt package recognizes it as an implementation of fmt.Scanner.
- r := new(big.Rat)
- _, err := fmt.Sscan("1.5000", r)
- if err != nil {
- log.Println("error scanning value:", err)
- } else {
- fmt.Println(r)
- }
- // Output: 3/2
-}
-
-func ExampleInt_Scan() {
- // The Scan function is rarely used directly;
- // the fmt package recognizes it as an implementation of fmt.Scanner.
- i := new(big.Int)
- _, err := fmt.Sscan("18446744073709551617", i)
- if err != nil {
- log.Println("error scanning value:", err)
- } else {
- fmt.Println(i)
- }
- // Output: 18446744073709551617
-}
-
-// This example demonstrates how to use big.Int to compute the smallest
-// Fibonacci number with 100 decimal digits and to test whether it is prime.
-func Example_fibonacci() {
- // Initialize two big ints with the first two numbers in the sequence.
- a := big.NewInt(0)
- b := big.NewInt(1)
-
- // Initialize limit as 10^99, the smallest integer with 100 digits.
- var limit big.Int
- limit.Exp(big.NewInt(10), big.NewInt(99), nil)
-
- // Loop while a is smaller than 1e100.
- for a.Cmp(&limit) < 0 {
- // Compute the next Fibonacci number, storing it in a.
- a.Add(a, b)
- // Swap a and b so that b is the next number in the sequence.
- a, b = b, a
- }
- fmt.Println(a) // 100-digit Fibonacci number
-
- // Test a for primality.
- // (ProbablyPrimes' argument sets the number of Miller-Rabin
- // rounds to be performed. 20 is a good value.)
- fmt.Println(a.ProbablyPrime(20))
-
- // Output:
- // 1344719667586153181419716641724567886890850696275767987106294472017884974410332069524504824747437757
- // false
-}
-
-// This example shows how to use big.Float to compute the square root of 2 with
-// a precision of 200 bits, and how to print the result as a decimal number.
-func Example_sqrt2() {
- // We'll do computations with 200 bits of precision in the mantissa.
- const prec = 200
-
- // Compute the square root of 2 using Newton's Method. We start with
- // an initial estimate for sqrt(2), and then iterate:
- // x_{n+1} = 1/2 * ( x_n + (2.0 / x_n) )
-
- // Since Newton's Method doubles the number of correct digits at each
- // iteration, we need at least log_2(prec) steps.
- steps := int(math.Log2(prec))
-
- // Initialize values we need for the computation.
- two := new(big.Float).SetPrec(prec).SetInt64(2)
- half := new(big.Float).SetPrec(prec).SetFloat64(0.5)
-
- // Use 1 as the initial estimate.
- x := new(big.Float).SetPrec(prec).SetInt64(1)
-
- // We use t as a temporary variable. There's no need to set its precision
- // since big.Float values with unset (== 0) precision automatically assume
- // the largest precision of the arguments when used as the result (receiver)
- // of a big.Float operation.
- t := new(big.Float)
-
- // Iterate.
- for i := 0; i <= steps; i++ {
- t.Quo(two, x) // t = 2.0 / x_n
- t.Add(x, t) // t = x_n + (2.0 / x_n)
- x.Mul(half, t) // x_{n+1} = 0.5 * t
- }
-
- // We can use the usual fmt.Printf verbs since big.Float implements fmt.Formatter
- fmt.Printf("sqrt(2) = %.50f\n", x)
-
- // Print the error between 2 and x*x.
- t.Mul(x, x) // t = x*x
- fmt.Printf("error = %e\n", t.Sub(two, t))
-
- // Output:
- // sqrt(2) = 1.41421356237309504880168872420969807856967187537695
- // error = 0.000000e+00
-}
diff --git a/src/cmd/compile/internal/big/float.go b/src/cmd/compile/internal/big/float.go
deleted file mode 100644
index 7a9c2b3..0000000
--- a/src/cmd/compile/internal/big/float.go
+++ /dev/null
@@ -1,1683 +0,0 @@
-// Copyright 2014 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.
-
-// This file implements multi-precision floating-point numbers.
-// Like in the GNU MPFR library (http://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
-// mode of an operation. This is a from-scratch implementation.
-
-package big
-
-import (
- "fmt"
- "math"
-)
-
-const debugFloat = false // enable for debugging
-
-// A nonzero finite Float represents a multi-precision floating point number
-//
-// sign × mantissa × 2**exponent
-//
-// with 0.5 <= mantissa < 1.0, and MinExp <= exponent <= MaxExp.
-// A Float may also be zero (+0, -0) or infinite (+Inf, -Inf).
-// All Floats are ordered, and the ordering of two Floats x and y
-// is defined by x.Cmp(y).
-//
-// Each Float value also has a precision, rounding mode, and accuracy.
-// The precision is the maximum number of mantissa bits available to
-// represent the value. The rounding mode specifies how a result should
-// be rounded to fit into the mantissa bits, and accuracy describes the
-// rounding error with respect to the exact result.
-//
-// Unless specified otherwise, all operations (including setters) that
-// specify a *Float variable for the result (usually via the receiver
-// with the exception of MantExp), round the numeric result according
-// to the precision and rounding mode of the result variable.
-//
-// If the provided result precision is 0 (see below), it is set to the
-// precision of the argument with the largest precision value before any
-// rounding takes place, and the rounding mode remains unchanged. Thus,
-// uninitialized Floats provided as result arguments will have their
-// precision set to a reasonable value determined by the operands and
-// their mode is the zero value for RoundingMode (ToNearestEven).
-//
-// By setting the desired precision to 24 or 53 and using matching rounding
-// mode (typically ToNearestEven), Float operations produce the same results
-// as the corresponding float32 or float64 IEEE-754 arithmetic for operands
-// that correspond to normal (i.e., not denormal) float32 or float64 numbers.
-// Exponent underflow and overflow lead to a 0 or an Infinity for different
-// values than IEEE-754 because Float exponents have a much larger range.
-//
-// The zero (uninitialized) value for a Float is ready to use and represents
-// the number +0.0 exactly, with precision 0 and rounding mode ToNearestEven.
-//
-type Float struct {
- prec uint32
- mode RoundingMode
- acc Accuracy
- form form
- neg bool
- mant nat
- exp int32
-}
-
-// An ErrNaN panic is raised by a Float operation that would lead to
-// a NaN under IEEE-754 rules. An ErrNaN implements the error interface.
-type ErrNaN struct {
- msg string
-}
-
-func (err ErrNaN) Error() string {
- return err.msg
-}
-
-// NewFloat allocates and returns a new Float set to x,
-// with precision 53 and rounding mode ToNearestEven.
-// NewFloat panics with ErrNaN if x is a NaN.
-func NewFloat(x float64) *Float {
- if math.IsNaN(x) {
- panic(ErrNaN{"NewFloat(NaN)"})
- }
- return new(Float).SetFloat64(x)
-}
-
-// Exponent and precision limits.
-const (
- MaxExp = math.MaxInt32 // largest supported exponent
- MinExp = math.MinInt32 // smallest supported exponent
- MaxPrec = math.MaxUint32 // largest (theoretically) supported precision; likely memory-limited
-)
-
-// Internal representation: The mantissa bits x.mant of a nonzero finite
-// Float x are stored in a nat slice long enough to hold up to x.prec bits;
-// the slice may (but doesn't have to) be shorter if the mantissa contains
-// trailing 0 bits. x.mant is normalized if the msb of x.mant == 1 (i.e.,
-// the msb is shifted all the way "to the left"). Thus, if the mantissa has
-// trailing 0 bits or x.prec is not a multiple of the the Word size _W,
-// x.mant[0] has trailing zero bits. The msb of the mantissa corresponds
-// to the value 0.5; the exponent x.exp shifts the binary point as needed.
-//
-// A zero or non-finite Float x ignores x.mant and x.exp.
-//
-// x form neg mant exp
-// ----------------------------------------------------------
-// ±0 zero sign - -
-// 0 < |x| < +Inf finite sign mantissa exponent
-// ±Inf inf sign - -
-
-// A form value describes the internal representation.
-type form byte
-
-// The form value order is relevant - do not change!
-const (
- zero form = iota
- finite
- inf
-)
-
-// RoundingMode determines how a Float value is rounded to the
-// desired precision. Rounding may change the Float value; the
-// rounding error is described by the Float's Accuracy.
-type RoundingMode byte
-
-// These constants define supported rounding modes.
-const (
- ToNearestEven RoundingMode = iota // == IEEE 754-2008 roundTiesToEven
- ToNearestAway // == IEEE 754-2008 roundTiesToAway
- ToZero // == IEEE 754-2008 roundTowardZero
- AwayFromZero // no IEEE 754-2008 equivalent
- ToNegativeInf // == IEEE 754-2008 roundTowardNegative
- ToPositiveInf // == IEEE 754-2008 roundTowardPositive
-)
-
-//go:generate stringer -type=RoundingMode
-
-// Accuracy describes the rounding error produced by the most recent
-// operation that generated a Float value, relative to the exact value.
-type Accuracy int8
-
-// Constants describing the Accuracy of a Float.
-const (
- Below Accuracy = -1
- Exact Accuracy = 0
- Above Accuracy = +1
-)
-
-//go:generate stringer -type=Accuracy
-
-// SetPrec sets z's precision to prec and returns the (possibly) rounded
-// value of z. Rounding occurs according to z's rounding mode if the mantissa
-// cannot be represented in prec bits without loss of precision.
-// SetPrec(0) maps all finite values to ±0; infinite values remain unchanged.
-// If prec > MaxPrec, it is set to MaxPrec.
-func (z *Float) SetPrec(prec uint) *Float {
- z.acc = Exact // optimistically assume no rounding is needed
-
- // special case
- if prec == 0 {
- z.prec = 0
- if z.form == finite {
- // truncate z to 0
- z.acc = makeAcc(z.neg)
- z.form = zero
- }
- return z
- }
-
- // general case
- if prec > MaxPrec {
- prec = MaxPrec
- }
- old := z.prec
- z.prec = uint32(prec)
- if z.prec < old {
- z.round(0)
- }
- return z
-}
-
-func makeAcc(above bool) Accuracy {
- if above {
- return Above
- }
- return Below
-}
-
-// SetMode sets z's rounding mode to mode and returns an exact z.
-// z remains unchanged otherwise.
-// z.SetMode(z.Mode()) is a cheap way to set z's accuracy to Exact.
-func (z *Float) SetMode(mode RoundingMode) *Float {
- z.mode = mode
- z.acc = Exact
- return z
-}
-
-// Prec returns the mantissa precision of x in bits.
-// The result may be 0 for |x| == 0 and |x| == Inf.
-func (x *Float) Prec() uint {
- return uint(x.prec)
-}
-
-// MinPrec returns the minimum precision required to represent x exactly
-// (i.e., the smallest prec before x.SetPrec(prec) would start rounding x).
-// The result is 0 for |x| == 0 and |x| == Inf.
-func (x *Float) MinPrec() uint {
- if x.form != finite {
- return 0
- }
- return uint(len(x.mant))*_W - x.mant.trailingZeroBits()
-}
-
-// Mode returns the rounding mode of x.
-func (x *Float) Mode() RoundingMode {
- return x.mode
-}
-
-// Acc returns the accuracy of x produced by the most recent operation.
-func (x *Float) Acc() Accuracy {
- return x.acc
-}
-
-// Sign returns:
-//
-// -1 if x < 0
-// 0 if x is ±0
-// +1 if x > 0
-//
-func (x *Float) Sign() int {
- if debugFloat {
- x.validate()
- }
- if x.form == zero {
- return 0
- }
- if x.neg {
- return -1
- }
- return 1
-}
-
-// MantExp breaks x into its mantissa and exponent components
-// and returns the exponent. If a non-nil mant argument is
-// provided its value is set to the mantissa of x, with the
-// same precision and rounding mode as x. The components
-// satisfy x == mant × 2**exp, with 0.5 <= |mant| < 1.0.
-// Calling MantExp with a nil argument is an efficient way to
-// get the exponent of the receiver.
-//
-// Special cases are:
-//
-// ( ±0).MantExp(mant) = 0, with mant set to ±0
-// (±Inf).MantExp(mant) = 0, with mant set to ±Inf
-//
-// x and mant may be the same in which case x is set to its
-// mantissa value.
-func (x *Float) MantExp(mant *Float) (exp int) {
- if debugFloat {
- x.validate()
- }
- if x.form == finite {
- exp = int(x.exp)
- }
- if mant != nil {
- mant.Copy(x)
- if mant.form == finite {
- mant.exp = 0
- }
- }
- return
-}
-
-func (z *Float) setExpAndRound(exp int64, sbit uint) {
- if exp < MinExp {
- // underflow
- z.acc = makeAcc(z.neg)
- z.form = zero
- return
- }
-
- if exp > MaxExp {
- // overflow
- z.acc = makeAcc(!z.neg)
- z.form = inf
- return
- }
-
- z.form = finite
- z.exp = int32(exp)
- z.round(sbit)
-}
-
-// SetMantExp sets z to mant × 2**exp and and returns z.
-// The result z has the same precision and rounding mode
-// as mant. SetMantExp is an inverse of MantExp but does
-// not require 0.5 <= |mant| < 1.0. Specifically:
-//
-// mant := new(Float)
-// new(Float).SetMantExp(mant, x.MantExp(mant)).Cmp(x) == 0
-//
-// Special cases are:
-//
-// z.SetMantExp( ±0, exp) = ±0
-// z.SetMantExp(±Inf, exp) = ±Inf
-//
-// z and mant may be the same in which case z's exponent
-// is set to exp.
-func (z *Float) SetMantExp(mant *Float, exp int) *Float {
- if debugFloat {
- z.validate()
- mant.validate()
- }
- z.Copy(mant)
- if z.form != finite {
- return z
- }
- z.setExpAndRound(int64(z.exp)+int64(exp), 0)
- return z
-}
-
-// Signbit returns true if x is negative or negative zero.
-func (x *Float) Signbit() bool {
- return x.neg
-}
-
-// IsInf reports whether x is +Inf or -Inf.
-func (x *Float) IsInf() bool {
- return x.form == inf
-}
-
-// IsInt reports whether x is an integer.
-// ±Inf values are not integers.
-func (x *Float) IsInt() bool {
- if debugFloat {
- x.validate()
- }
- // special cases
- if x.form != finite {
- return x.form == zero
- }
- // x.form == finite
- if x.exp <= 0 {
- return false
- }
- // x.exp > 0
- return x.prec <= uint32(x.exp) || x.MinPrec() <= uint(x.exp) // not enough bits for fractional mantissa
-}
-
-// debugging support
-func (x *Float) validate() {
- if !debugFloat {
- // avoid performance bugs
- panic("validate called but debugFloat is not set")
- }
- if x.form != finite {
- return
- }
- m := len(x.mant)
- if m == 0 {
- panic("nonzero finite number with empty mantissa")
- }
- const msb = 1 << (_W - 1)
- if x.mant[m-1]&msb == 0 {
- panic(fmt.Sprintf("msb not set in last word %#x of %s", x.mant[m-1], x.Text('p', 0)))
- }
- if x.prec == 0 {
- panic("zero precision finite number")
- }
-}
-
-// round rounds z according to z.mode to z.prec bits and sets z.acc accordingly.
-// sbit must be 0 or 1 and summarizes any "sticky bit" information one might
-// have before calling round. z's mantissa must be normalized (with the msb set)
-// or empty.
-//
-// CAUTION: The rounding modes ToNegativeInf, ToPositiveInf are affected by the
-// sign of z. For correct rounding, the sign of z must be set correctly before
-// calling round.
-func (z *Float) round(sbit uint) {
- if debugFloat {
- z.validate()
- }
-
- z.acc = Exact
- if z.form != finite {
- // ±0 or ±Inf => nothing left to do
- return
- }
- // z.form == finite && len(z.mant) > 0
- // m > 0 implies z.prec > 0 (checked by validate)
-
- m := uint32(len(z.mant)) // present mantissa length in words
- bits := m * _W // present mantissa bits; bits > 0
- if bits <= z.prec {
- // mantissa fits => nothing to do
- return
- }
- // bits > z.prec
-
- // Rounding is based on two bits: the rounding bit (rbit) and the
- // sticky bit (sbit). The rbit is the bit immediately before the
- // z.prec leading mantissa bits (the "0.5"). The sbit is set if any
- // of the bits before the rbit are set (the "0.25", "0.125", etc.):
- //
- // rbit sbit => "fractional part"
- //
- // 0 0 == 0
- // 0 1 > 0 , < 0.5
- // 1 0 == 0.5
- // 1 1 > 0.5, < 1.0
-
- // bits > z.prec: mantissa too large => round
- r := uint(bits - z.prec - 1) // rounding bit position; r >= 0
- rbit := z.mant.bit(r) & 1 // rounding bit; be safe and ensure it's a single bit
- if sbit == 0 {
- // TODO(gri) if rbit != 0 we don't need to compute sbit for some rounding modes (optimization)
- sbit = z.mant.sticky(r)
- }
- sbit &= 1 // be safe and ensure it's a single bit
-
- // cut off extra words
- n := (z.prec + (_W - 1)) / _W // mantissa length in words for desired precision
- if m > n {
- copy(z.mant, z.mant[m-n:]) // move n last words to front
- z.mant = z.mant[:n]
- }
-
- // determine number of trailing zero bits (ntz) and compute lsb mask of mantissa's least-significant word
- ntz := n*_W - z.prec // 0 <= ntz < _W
- lsb := Word(1) << ntz
-
- // round if result is inexact
- if rbit|sbit != 0 {
- // Make rounding decision: The result mantissa is truncated ("rounded down")
- // by default. Decide if we need to increment, or "round up", the (unsigned)
- // mantissa.
- inc := false
- switch z.mode {
- case ToNegativeInf:
- inc = z.neg
- case ToZero:
- // nothing to do
- case ToNearestEven:
- inc = rbit != 0 && (sbit != 0 || z.mant[0]&lsb != 0)
- case ToNearestAway:
- inc = rbit != 0
- case AwayFromZero:
- inc = true
- case ToPositiveInf:
- inc = !z.neg
- default:
- panic("unreachable")
- }
-
- // A positive result (!z.neg) is Above the exact result if we increment,
- // and it's Below if we truncate (Exact results require no rounding).
- // For a negative result (z.neg) it is exactly the opposite.
- z.acc = makeAcc(inc != z.neg)
-
- if inc {
- // add 1 to mantissa
- if addVW(z.mant, z.mant, lsb) != 0 {
- // mantissa overflow => adjust exponent
- if z.exp >= MaxExp {
- // exponent overflow
- z.form = inf
- return
- }
- z.exp++
- // adjust mantissa: divide by 2 to compensate for exponent adjustment
- shrVU(z.mant, z.mant, 1)
- // set msb == carry == 1 from the mantissa overflow above
- const msb = 1 << (_W - 1)
- z.mant[n-1] |= msb
- }
- }
- }
-
- // zero out trailing bits in least-significant word
- z.mant[0] &^= lsb - 1
-
- if debugFloat {
- z.validate()
- }
-}
-
-func (z *Float) setBits64(neg bool, x uint64) *Float {
- if z.prec == 0 {
- z.prec = 64
- }
- z.acc = Exact
- z.neg = neg
- if x == 0 {
- z.form = zero
- return z
- }
- // x != 0
- z.form = finite
- s := nlz64(x)
- z.mant = z.mant.setUint64(x << s)
- z.exp = int32(64 - s) // always fits
- if z.prec < 64 {
- z.round(0)
- }
- return z
-}
-
-// SetUint64 sets z to the (possibly rounded) value of x and returns z.
-// If z's precision is 0, it is changed to 64 (and rounding will have
-// no effect).
-func (z *Float) SetUint64(x uint64) *Float {
- return z.setBits64(false, x)
-}
-
-// SetInt64 sets z to the (possibly rounded) value of x and returns z.
-// If z's precision is 0, it is changed to 64 (and rounding will have
-// no effect).
-func (z *Float) SetInt64(x int64) *Float {
- u := x
- if u < 0 {
- u = -u
- }
- // We cannot simply call z.SetUint64(uint64(u)) and change
- // the sign afterwards because the sign affects rounding.
- return z.setBits64(x < 0, uint64(u))
-}
-
-// SetFloat64 sets z to the (possibly rounded) value of x and returns z.
-// If z's precision is 0, it is changed to 53 (and rounding will have
-// no effect). SetFloat64 panics with ErrNaN if x is a NaN.
-func (z *Float) SetFloat64(x float64) *Float {
- if z.prec == 0 {
- z.prec = 53
- }
- if math.IsNaN(x) {
- panic(ErrNaN{"Float.SetFloat64(NaN)"})
- }
- z.acc = Exact
- z.neg = math.Signbit(x) // handle -0, -Inf correctly
- if x == 0 {
- z.form = zero
- return z
- }
- if math.IsInf(x, 0) {
- z.form = inf
- return z
- }
- // normalized x != 0
- z.form = finite
- fmant, exp := math.Frexp(x) // get normalized mantissa
- z.mant = z.mant.setUint64(1<<63 | math.Float64bits(fmant)<<11)
- z.exp = int32(exp) // always fits
- if z.prec < 53 {
- z.round(0)
- }
- return z
-}
-
-// fnorm normalizes mantissa m by shifting it to the left
-// such that the msb of the most-significant word (msw) is 1.
-// It returns the shift amount. It assumes that len(m) != 0.
-func fnorm(m nat) int64 {
- if debugFloat && (len(m) == 0 || m[len(m)-1] == 0) {
- panic("msw of mantissa is 0")
- }
- s := nlz(m[len(m)-1])
- if s > 0 {
- c := shlVU(m, m, s)
- if debugFloat && c != 0 {
- panic("nlz or shlVU incorrect")
- }
- }
- return int64(s)
-}
-
-// SetInt sets z to the (possibly rounded) value of x and returns z.
-// If z's precision is 0, it is changed to the larger of x.BitLen()
-// or 64 (and rounding will have no effect).
-func (z *Float) SetInt(x *Int) *Float {
- // TODO(gri) can be more efficient if z.prec > 0
- // but small compared to the size of x, or if there
- // are many trailing 0's.
- bits := uint32(x.BitLen())
- if z.prec == 0 {
- z.prec = umax32(bits, 64)
- }
- z.acc = Exact
- z.neg = x.neg
- if len(x.abs) == 0 {
- z.form = zero
- return z
- }
- // x != 0
- z.mant = z.mant.set(x.abs)
- fnorm(z.mant)
- z.setExpAndRound(int64(bits), 0)
- return z
-}
-
-// SetRat sets z to the (possibly rounded) value of x and returns z.
-// If z's precision is 0, it is changed to the largest of a.BitLen(),
-// b.BitLen(), or 64; with x = a/b.
-func (z *Float) SetRat(x *Rat) *Float {
- if x.IsInt() {
- return z.SetInt(x.Num())
- }
- var a, b Float
- a.SetInt(x.Num())
- b.SetInt(x.Denom())
- if z.prec == 0 {
- z.prec = umax32(a.prec, b.prec)
- }
- return z.Quo(&a, &b)
-}
-
-// SetInf sets z to the infinite Float -Inf if signbit is
-// set, or +Inf if signbit is not set, and returns z. The
-// precision of z is unchanged and the result is always
-// Exact.
-func (z *Float) SetInf(signbit bool) *Float {
- z.acc = Exact
- z.form = inf
- z.neg = signbit
- return z
-}
-
-// Set sets z to the (possibly rounded) value of x and returns z.
-// If z's precision is 0, it is changed to the precision of x
-// before setting z (and rounding will have no effect).
-// Rounding is performed according to z's precision and rounding
-// mode; and z's accuracy reports the result error relative to the
-// exact (not rounded) result.
-func (z *Float) Set(x *Float) *Float {
- if debugFloat {
- x.validate()
- }
- z.acc = Exact
- if z != x {
- z.form = x.form
- z.neg = x.neg
- if x.form == finite {
- z.exp = x.exp
- z.mant = z.mant.set(x.mant)
- }
- if z.prec == 0 {
- z.prec = x.prec
- } else if z.prec < x.prec {
- z.round(0)
- }
- }
- return z
-}
-
-// Copy sets z to x, with the same precision, rounding mode, and
-// accuracy as x, and returns z. x is not changed even if z and
-// x are the same.
-func (z *Float) Copy(x *Float) *Float {
- if debugFloat {
- x.validate()
- }
- if z != x {
- z.prec = x.prec
- z.mode = x.mode
- z.acc = x.acc
- z.form = x.form
- z.neg = x.neg
- if z.form == finite {
- z.mant = z.mant.set(x.mant)
- z.exp = x.exp
- }
- }
- return z
-}
-
-// msb32 returns the 32 most significant bits of x.
-func msb32(x nat) uint32 {
- i := len(x) - 1
- if i < 0 {
- return 0
- }
- if debugFloat && x[i]&(1<<(_W-1)) == 0 {
- panic("x not normalized")
- }
- switch _W {
- case 32:
- return uint32(x[i])
- case 64:
- return uint32(x[i] >> 32)
- }
- panic("unreachable")
-}
-
-// msb64 returns the 64 most significant bits of x.
-func msb64(x nat) uint64 {
- i := len(x) - 1
- if i < 0 {
- return 0
- }
- if debugFloat && x[i]&(1<<(_W-1)) == 0 {
- panic("x not normalized")
- }
- switch _W {
- case 32:
- v := uint64(x[i]) << 32
- if i > 0 {
- v |= uint64(x[i-1])
- }
- return v
- case 64:
- return uint64(x[i])
- }
- panic("unreachable")
-}
-
-// Uint64 returns the unsigned integer resulting from truncating x
-// towards zero. If 0 <= x <= math.MaxUint64, the result is Exact
-// if x is an integer and Below otherwise.
-// The result is (0, Above) for x < 0, and (math.MaxUint64, Below)
-// for x > math.MaxUint64.
-func (x *Float) Uint64() (uint64, Accuracy) {
- if debugFloat {
- x.validate()
- }
-
- switch x.form {
- case finite:
- if x.neg {
- return 0, Above
- }
- // 0 < x < +Inf
- if x.exp <= 0 {
- // 0 < x < 1
- return 0, Below
- }
- // 1 <= x < Inf
- if x.exp <= 64 {
- // u = trunc(x) fits into a uint64
- u := msb64(x.mant) >> (64 - uint32(x.exp))
- if x.MinPrec() <= 64 {
- return u, Exact
- }
- return u, Below // x truncated
- }
- // x too large
- return math.MaxUint64, Below
-
- case zero:
- return 0, Exact
-
- case inf:
- if x.neg {
- return 0, Above
- }
- return math.MaxUint64, Below
- }
-
- panic("unreachable")
-}
-
-// Int64 returns the integer resulting from truncating x towards zero.
-// If math.MinInt64 <= x <= math.MaxInt64, the result is Exact if x is
-// an integer, and Above (x < 0) or Below (x > 0) otherwise.
-// The result is (math.MinInt64, Above) for x < math.MinInt64,
-// and (math.MaxInt64, Below) for x > math.MaxInt64.
-func (x *Float) Int64() (int64, Accuracy) {
- if debugFloat {
- x.validate()
- }
-
- switch x.form {
- case finite:
- // 0 < |x| < +Inf
- acc := makeAcc(x.neg)
- if x.exp <= 0 {
- // 0 < |x| < 1
- return 0, acc
- }
- // x.exp > 0
-
- // 1 <= |x| < +Inf
- if x.exp <= 63 {
- // i = trunc(x) fits into an int64 (excluding math.MinInt64)
- i := int64(msb64(x.mant) >> (64 - uint32(x.exp)))
- if x.neg {
- i = -i
- }
- if x.MinPrec() <= uint(x.exp) {
- return i, Exact
- }
- return i, acc // x truncated
- }
- if x.neg {
- // check for special case x == math.MinInt64 (i.e., x == -(0.5 << 64))
- if x.exp == 64 && x.MinPrec() == 1 {
- acc = Exact
- }
- return math.MinInt64, acc
- }
- // x too large
- return math.MaxInt64, Below
-
- case zero:
- return 0, Exact
-
- case inf:
- if x.neg {
- return math.MinInt64, Above
- }
- return math.MaxInt64, Below
- }
-
- panic("unreachable")
-}
-
-// Float32 returns the float32 value nearest to x. If x is too small to be
-// represented by a float32 (|x| < math.SmallestNonzeroFloat32), the result
-// is (0, Below) or (-0, Above), respectively, depending on the sign of x.
-// If x is too large to be represented by a float32 (|x| > math.MaxFloat32),
-// the result is (+Inf, Above) or (-Inf, Below), depending on the sign of x.
-func (x *Float) Float32() (float32, Accuracy) {
- if debugFloat {
- x.validate()
- }
-
- switch x.form {
- case finite:
- // 0 < |x| < +Inf
-
- const (
- fbits = 32 // float size
- mbits = 23 // mantissa size (excluding implicit msb)
- ebits = fbits - mbits - 1 // 8 exponent size
- bias = 1<<(ebits-1) - 1 // 127 exponent bias
- dmin = 1 - bias - mbits // -149 smallest unbiased exponent (denormal)
- emin = 1 - bias // -126 smallest unbiased exponent (normal)
- emax = bias // 127 largest unbiased exponent (normal)
- )
-
- // Float mantissa m is 0.5 <= m < 1.0; compute exponent e for float32 mantissa.
- e := x.exp - 1 // exponent for normal mantissa m with 1.0 <= m < 2.0
-
- // Compute precision p for float32 mantissa.
- // If the exponent is too small, we have a denormal number before
- // rounding and fewer than p mantissa bits of precision available
- // (the exponent remains fixed but the mantissa gets shifted right).
- p := mbits + 1 // precision of normal float
- if e < emin {
- // recompute precision
- p = mbits + 1 - emin + int(e)
- // If p == 0, the mantissa of x is shifted so much to the right
- // that its msb falls immediately to the right of the float32
- // mantissa space. In other words, if the smallest denormal is
- // considered "1.0", for p == 0, the mantissa value m is >= 0.5.
- // If m > 0.5, it is rounded up to 1.0; i.e., the smallest denormal.
- // If m == 0.5, it is rounded down to even, i.e., 0.0.
- // If p < 0, the mantissa value m is <= "0.25" which is never rounded up.
- if p < 0 /* m <= 0.25 */ || p == 0 && x.mant.sticky(uint(len(x.mant))*_W-1) == 0 /* m == 0.5 */ {
- // underflow to ±0
- if x.neg {
- var z float32
- return -z, Above
- }
- return 0.0, Below
- }
- // otherwise, round up
- // We handle p == 0 explicitly because it's easy and because
- // Float.round doesn't support rounding to 0 bits of precision.
- if p == 0 {
- if x.neg {
- return -math.SmallestNonzeroFloat32, Below
- }
- return math.SmallestNonzeroFloat32, Above
- }
- }
- // p > 0
-
- // round
- var r Float
- r.prec = uint32(p)
- r.Set(x)
- e = r.exp - 1
-
- // Rounding may have caused r to overflow to ±Inf
- // (rounding never causes underflows to 0).
- // If the exponent is too large, also overflow to ±Inf.
- if r.form == inf || e > emax {
- // overflow
- if x.neg {
- return float32(math.Inf(-1)), Below
- }
- return float32(math.Inf(+1)), Above
- }
- // e <= emax
-
- // Determine sign, biased exponent, and mantissa.
- var sign, bexp, mant uint32
- if x.neg {
- sign = 1 << (fbits - 1)
- }
-
- // Rounding may have caused a denormal number to
- // become normal. Check again.
- if e < emin {
- // denormal number: recompute precision
- // Since rounding may have at best increased precision
- // and we have eliminated p <= 0 early, we know p > 0.
- // bexp == 0 for denormals
- p = mbits + 1 - emin + int(e)
- mant = msb32(r.mant) >> uint(fbits-p)
- } else {
- // normal number: emin <= e <= emax
- bexp = uint32(e+bias) << mbits
- mant = msb32(r.mant) >> ebits & (1<<mbits - 1) // cut off msb (implicit 1 bit)
- }
-
- return math.Float32frombits(sign | bexp | mant), r.acc
-
- case zero:
- if x.neg {
- var z float32
- return -z, Exact
- }
- return 0.0, Exact
-
- case inf:
- if x.neg {
- return float32(math.Inf(-1)), Exact
- }
- return float32(math.Inf(+1)), Exact
- }
-
- panic("unreachable")
-}
-
-// Float64 returns the float64 value nearest to x. If x is too small to be
-// represented by a float64 (|x| < math.SmallestNonzeroFloat64), the result
-// is (0, Below) or (-0, Above), respectively, depending on the sign of x.
-// If x is too large to be represented by a float64 (|x| > math.MaxFloat64),
-// the result is (+Inf, Above) or (-Inf, Below), depending on the sign of x.
-func (x *Float) Float64() (float64, Accuracy) {
- if debugFloat {
- x.validate()
- }
-
- switch x.form {
- case finite:
- // 0 < |x| < +Inf
-
- const (
- fbits = 64 // float size
- mbits = 52 // mantissa size (excluding implicit msb)
- ebits = fbits - mbits - 1 // 11 exponent size
- bias = 1<<(ebits-1) - 1 // 1023 exponent bias
- dmin = 1 - bias - mbits // -1074 smallest unbiased exponent (denormal)
- emin = 1 - bias // -1022 smallest unbiased exponent (normal)
- emax = bias // 1023 largest unbiased exponent (normal)
- )
-
- // Float mantissa m is 0.5 <= m < 1.0; compute exponent e for float64 mantissa.
- e := x.exp - 1 // exponent for normal mantissa m with 1.0 <= m < 2.0
-
- // Compute precision p for float64 mantissa.
- // If the exponent is too small, we have a denormal number before
- // rounding and fewer than p mantissa bits of precision available
- // (the exponent remains fixed but the mantissa gets shifted right).
- p := mbits + 1 // precision of normal float
- if e < emin {
- // recompute precision
- p = mbits + 1 - emin + int(e)
- // If p == 0, the mantissa of x is shifted so much to the right
- // that its msb falls immediately to the right of the float64
- // mantissa space. In other words, if the smallest denormal is
- // considered "1.0", for p == 0, the mantissa value m is >= 0.5.
- // If m > 0.5, it is rounded up to 1.0; i.e., the smallest denormal.
- // If m == 0.5, it is rounded down to even, i.e., 0.0.
- // If p < 0, the mantissa value m is <= "0.25" which is never rounded up.
- if p < 0 /* m <= 0.25 */ || p == 0 && x.mant.sticky(uint(len(x.mant))*_W-1) == 0 /* m == 0.5 */ {
- // underflow to ±0
- if x.neg {
- var z float64
- return -z, Above
- }
- return 0.0, Below
- }
- // otherwise, round up
- // We handle p == 0 explicitly because it's easy and because
- // Float.round doesn't support rounding to 0 bits of precision.
- if p == 0 {
- if x.neg {
- return -math.SmallestNonzeroFloat64, Below
- }
- return math.SmallestNonzeroFloat64, Above
- }
- }
- // p > 0
-
- // round
- var r Float
- r.prec = uint32(p)
- r.Set(x)
- e = r.exp - 1
-
- // Rounding may have caused r to overflow to ±Inf
- // (rounding never causes underflows to 0).
- // If the exponent is too large, also overflow to ±Inf.
- if r.form == inf || e > emax {
- // overflow
- if x.neg {
- return math.Inf(-1), Below
- }
- return math.Inf(+1), Above
- }
- // e <= emax
-
- // Determine sign, biased exponent, and mantissa.
- var sign, bexp, mant uint64
- if x.neg {
- sign = 1 << (fbits - 1)
- }
-
- // Rounding may have caused a denormal number to
- // become normal. Check again.
- if e < emin {
- // denormal number: recompute precision
- // Since rounding may have at best increased precision
- // and we have eliminated p <= 0 early, we know p > 0.
- // bexp == 0 for denormals
- p = mbits + 1 - emin + int(e)
- mant = msb64(r.mant) >> uint(fbits-p)
- } else {
- // normal number: emin <= e <= emax
- bexp = uint64(e+bias) << mbits
- mant = msb64(r.mant) >> ebits & (1<<mbits - 1) // cut off msb (implicit 1 bit)
- }
-
- return math.Float64frombits(sign | bexp | mant), r.acc
-
- case zero:
- if x.neg {
- var z float64
- return -z, Exact
- }
- return 0.0, Exact
-
- case inf:
- if x.neg {
- return math.Inf(-1), Exact
- }
- return math.Inf(+1), Exact
- }
-
- panic("unreachable")
-}
-
-// Int returns the result of truncating x towards zero;
-// or nil if x is an infinity.
-// The result is Exact if x.IsInt(); otherwise it is Below
-// for x > 0, and Above for x < 0.
-// If a non-nil *Int argument z is provided, Int stores
-// the result in z instead of allocating a new Int.
-func (x *Float) Int(z *Int) (*Int, Accuracy) {
- if debugFloat {
- x.validate()
- }
-
- if z == nil && x.form <= finite {
- z = new(Int)
- }
-
- switch x.form {
- case finite:
- // 0 < |x| < +Inf
- acc := makeAcc(x.neg)
- if x.exp <= 0 {
- // 0 < |x| < 1
- return z.SetInt64(0), acc
- }
- // x.exp > 0
-
- // 1 <= |x| < +Inf
- // determine minimum required precision for x
- allBits := uint(len(x.mant)) * _W
- exp := uint(x.exp)
- if x.MinPrec() <= exp {
- acc = Exact
- }
- // shift mantissa as needed
- if z == nil {
- z = new(Int)
- }
- z.neg = x.neg
- switch {
- case exp > allBits:
- z.abs = z.abs.shl(x.mant, exp-allBits)
- default:
- z.abs = z.abs.set(x.mant)
- case exp < allBits:
- z.abs = z.abs.shr(x.mant, allBits-exp)
- }
- return z, acc
-
- case zero:
- return z.SetInt64(0), Exact
-
- case inf:
- return nil, makeAcc(x.neg)
- }
-
- panic("unreachable")
-}
-
-// Rat returns the rational number corresponding to x;
-// or nil if x is an infinity.
-// The result is Exact if x is not an Inf.
-// If a non-nil *Rat argument z is provided, Rat stores
-// the result in z instead of allocating a new Rat.
-func (x *Float) Rat(z *Rat) (*Rat, Accuracy) {
- if debugFloat {
- x.validate()
- }
-
- if z == nil && x.form <= finite {
- z = new(Rat)
- }
-
- switch x.form {
- case finite:
- // 0 < |x| < +Inf
- allBits := int32(len(x.mant)) * _W
- // build up numerator and denominator
- z.a.neg = x.neg
- switch {
- case x.exp > allBits:
- z.a.abs = z.a.abs.shl(x.mant, uint(x.exp-allBits))
- z.b.abs = z.b.abs[:0] // == 1 (see Rat)
- // z already in normal form
- default:
- z.a.abs = z.a.abs.set(x.mant)
- z.b.abs = z.b.abs[:0] // == 1 (see Rat)
- // z already in normal form
- case x.exp < allBits:
- z.a.abs = z.a.abs.set(x.mant)
- t := z.b.abs.setUint64(1)
- z.b.abs = t.shl(t, uint(allBits-x.exp))
- z.norm()
- }
- return z, Exact
-
- case zero:
- return z.SetInt64(0), Exact
-
- case inf:
- return nil, makeAcc(x.neg)
- }
-
- panic("unreachable")
-}
-
-// Abs sets z to the (possibly rounded) value |x| (the absolute value of x)
-// and returns z.
-func (z *Float) Abs(x *Float) *Float {
- z.Set(x)
- z.neg = false
- return z
-}
-
-// Neg sets z to the (possibly rounded) value of x with its sign negated,
-// and returns z.
-func (z *Float) Neg(x *Float) *Float {
- z.Set(x)
- z.neg = !z.neg
- return z
-}
-
-func validateBinaryOperands(x, y *Float) {
- if !debugFloat {
- // avoid performance bugs
- panic("validateBinaryOperands called but debugFloat is not set")
- }
- if len(x.mant) == 0 {
- panic("empty mantissa for x")
- }
- if len(y.mant) == 0 {
- panic("empty mantissa for y")
- }
-}
-
-// z = x + y, ignoring signs of x and y for the addition
-// but using the sign of z for rounding the result.
-// x and y must have a non-empty mantissa and valid exponent.
-func (z *Float) uadd(x, y *Float) {
- // Note: This implementation requires 2 shifts most of the
- // time. It is also inefficient if exponents or precisions
- // differ by wide margins. The following article describes
- // an efficient (but much more complicated) implementation
- // compatible with the internal representation used here:
- //
- // Vincent Lefèvre: "The Generic Multiple-Precision Floating-
- // Point Addition With Exact Rounding (as in the MPFR Library)"
- // http://www.vinc17.net/research/papers/rnc6.pdf
-
- if debugFloat {
- validateBinaryOperands(x, y)
- }
-
- // compute exponents ex, ey for mantissa with "binary point"
- // on the right (mantissa.0) - use int64 to avoid overflow
- ex := int64(x.exp) - int64(len(x.mant))*_W
- ey := int64(y.exp) - int64(len(y.mant))*_W
-
- // TODO(gri) having a combined add-and-shift primitive
- // could make this code significantly faster
- switch {
- case ex < ey:
- // cannot re-use z.mant w/o testing for aliasing
- t := nat(nil).shl(y.mant, uint(ey-ex))
- z.mant = z.mant.add(x.mant, t)
- default:
- // ex == ey, no shift needed
- z.mant = z.mant.add(x.mant, y.mant)
- case ex > ey:
- // cannot re-use z.mant w/o testing for aliasing
- t := nat(nil).shl(x.mant, uint(ex-ey))
- z.mant = z.mant.add(t, y.mant)
- ex = ey
- }
- // len(z.mant) > 0
-
- z.setExpAndRound(ex+int64(len(z.mant))*_W-fnorm(z.mant), 0)
-}
-
-// z = x - y for |x| > |y|, ignoring signs of x and y for the subtraction
-// but using the sign of z for rounding the result.
-// x and y must have a non-empty mantissa and valid exponent.
-func (z *Float) usub(x, y *Float) {
- // This code is symmetric to uadd.
- // We have not factored the common code out because
- // eventually uadd (and usub) should be optimized
- // by special-casing, and the code will diverge.
-
- if debugFloat {
- validateBinaryOperands(x, y)
- }
-
- ex := int64(x.exp) - int64(len(x.mant))*_W
- ey := int64(y.exp) - int64(len(y.mant))*_W
-
- switch {
- case ex < ey:
- // cannot re-use z.mant w/o testing for aliasing
- t := nat(nil).shl(y.mant, uint(ey-ex))
- z.mant = t.sub(x.mant, t)
- default:
- // ex == ey, no shift needed
- z.mant = z.mant.sub(x.mant, y.mant)
- case ex > ey:
- // cannot re-use z.mant w/o testing for aliasing
- t := nat(nil).shl(x.mant, uint(ex-ey))
- z.mant = t.sub(t, y.mant)
- ex = ey
- }
-
- // operands may have canceled each other out
- if len(z.mant) == 0 {
- z.acc = Exact
- z.form = zero
- z.neg = false
- return
- }
- // len(z.mant) > 0
-
- z.setExpAndRound(ex+int64(len(z.mant))*_W-fnorm(z.mant), 0)
-}
-
-// z = x * y, ignoring signs of x and y for the multiplication
-// but using the sign of z for rounding the result.
-// x and y must have a non-empty mantissa and valid exponent.
-func (z *Float) umul(x, y *Float) {
- if debugFloat {
- validateBinaryOperands(x, y)
- }
-
- // Note: This is doing too much work if the precision
- // of z is less than the sum of the precisions of x
- // and y which is often the case (e.g., if all floats
- // have the same precision).
- // TODO(gri) Optimize this for the common case.
-
- e := int64(x.exp) + int64(y.exp)
- z.mant = z.mant.mul(x.mant, y.mant)
-
- z.setExpAndRound(e-fnorm(z.mant), 0)
-}
-
-// z = x / y, ignoring signs of x and y for the division
-// but using the sign of z for rounding the result.
-// x and y must have a non-empty mantissa and valid exponent.
-func (z *Float) uquo(x, y *Float) {
- if debugFloat {
- validateBinaryOperands(x, y)
- }
-
- // mantissa length in words for desired result precision + 1
- // (at least one extra bit so we get the rounding bit after
- // the division)
- n := int(z.prec/_W) + 1
-
- // compute adjusted x.mant such that we get enough result precision
- xadj := x.mant
- if d := n - len(x.mant) + len(y.mant); d > 0 {
- // d extra words needed => add d "0 digits" to x
- xadj = make(nat, len(x.mant)+d)
- copy(xadj[d:], x.mant)
- }
- // TODO(gri): If we have too many digits (d < 0), we should be able
- // to shorten x for faster division. But we must be extra careful
- // with rounding in that case.
-
- // Compute d before division since there may be aliasing of x.mant
- // (via xadj) or y.mant with z.mant.
- d := len(xadj) - len(y.mant)
-
- // divide
- var r nat
- z.mant, r = z.mant.div(nil, xadj, y.mant)
- e := int64(x.exp) - int64(y.exp) - int64(d-len(z.mant))*_W
-
- // The result is long enough to include (at least) the rounding bit.
- // If there's a non-zero remainder, the corresponding fractional part
- // (if it were computed), would have a non-zero sticky bit (if it were
- // zero, it couldn't have a non-zero remainder).
- var sbit uint
- if len(r) > 0 {
- sbit = 1
- }
-
- z.setExpAndRound(e-fnorm(z.mant), sbit)
-}
-
-// ucmp returns -1, 0, or +1, depending on whether
-// |x| < |y|, |x| == |y|, or |x| > |y|.
-// x and y must have a non-empty mantissa and valid exponent.
-func (x *Float) ucmp(y *Float) int {
- if debugFloat {
- validateBinaryOperands(x, y)
- }
-
- switch {
- case x.exp < y.exp:
- return -1
- case x.exp > y.exp:
- return +1
- }
- // x.exp == y.exp
-
- // compare mantissas
- i := len(x.mant)
- j := len(y.mant)
- for i > 0 || j > 0 {
- var xm, ym Word
- if i > 0 {
- i--
- xm = x.mant[i]
- }
- if j > 0 {
- j--
- ym = y.mant[j]
- }
- switch {
- case xm < ym:
- return -1
- case xm > ym:
- return +1
- }
- }
-
- return 0
-}
-
-// Handling of sign bit as defined by IEEE 754-2008, section 6.3:
-//
-// When neither the inputs nor result are NaN, the sign of a product or
-// quotient is the exclusive OR of the operands’ signs; the sign of a sum,
-// or of a difference x−y regarded as a sum x+(−y), differs from at most
-// one of the addends’ signs; and the sign of the result of conversions,
-// the quantize operation, the roundToIntegral operations, and the
-// roundToIntegralExact (see 5.3.1) is the sign of the first or only operand.
-// These rules shall apply even when operands or results are zero or infinite.
-//
-// When the sum of two operands with opposite signs (or the difference of
-// two operands with like signs) is exactly zero, the sign of that sum (or
-// difference) shall be +0 in all rounding-direction attributes except
-// roundTowardNegative; under that attribute, the sign of an exact zero
-// sum (or difference) shall be −0. However, x+x = x−(−x) retains the same
-// sign as x even when x is zero.
-//
-// See also: https://play.golang.org/p/RtH3UCt5IH
-
-// Add sets z to the rounded sum x+y and returns z. If z's precision is 0,
-// it is changed to the larger of x's or y's precision before the operation.
-// Rounding is performed according to z's precision and rounding mode; and
-// 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()
- y.validate()
- }
-
- if z.prec == 0 {
- z.prec = umax32(x.prec, y.prec)
- }
-
- if x.form == finite && y.form == finite {
- // x + y (common case)
- z.neg = x.neg
- if x.neg == y.neg {
- // x + y == x + y
- // (-x) + (-y) == -(x + y)
- z.uadd(x, y)
- } else {
- // x + (-y) == x - y == -(y - x)
- // (-x) + y == y - x == -(x - y)
- if x.ucmp(y) > 0 {
- z.usub(x, y)
- } else {
- z.neg = !z.neg
- z.usub(y, x)
- }
- }
- return z
- }
-
- if x.form == inf && y.form == inf && x.neg != y.neg {
- // +Inf + -Inf
- // -Inf + +Inf
- // value of z is undefined but make sure it's valid
- z.acc = Exact
- z.form = zero
- z.neg = false
- panic(ErrNaN{"addition of infinities with opposite signs"})
- }
-
- if x.form == zero && y.form == zero {
- // ±0 + ±0
- z.acc = Exact
- z.form = zero
- z.neg = x.neg && y.neg // -0 + -0 == -0
- return z
- }
-
- if x.form == inf || y.form == zero {
- // ±Inf + y
- // x + ±0
- return z.Set(x)
- }
-
- // ±0 + y
- // x + ±Inf
- return z.Set(y)
-}
-
-// Sub sets z to the rounded difference x-y and returns z.
-// Precision, rounding, and accuracy reporting are as for Add.
-// Sub panics with ErrNaN if x and y are infinities with equal
-// signs. The value of z is undefined in that case.
-func (z *Float) Sub(x, y *Float) *Float {
- if debugFloat {
- x.validate()
- y.validate()
- }
-
- if z.prec == 0 {
- z.prec = umax32(x.prec, y.prec)
- }
-
- if x.form == finite && y.form == finite {
- // x - y (common case)
- z.neg = x.neg
- if x.neg != y.neg {
- // x - (-y) == x + y
- // (-x) - y == -(x + y)
- z.uadd(x, y)
- } else {
- // x - y == x - y == -(y - x)
- // (-x) - (-y) == y - x == -(x - y)
- if x.ucmp(y) > 0 {
- z.usub(x, y)
- } else {
- z.neg = !z.neg
- z.usub(y, x)
- }
- }
- return z
- }
-
- if x.form == inf && y.form == inf && x.neg == y.neg {
- // +Inf - +Inf
- // -Inf - -Inf
- // value of z is undefined but make sure it's valid
- z.acc = Exact
- z.form = zero
- z.neg = false
- panic(ErrNaN{"subtraction of infinities with equal signs"})
- }
-
- if x.form == zero && y.form == zero {
- // ±0 - ±0
- z.acc = Exact
- z.form = zero
- z.neg = x.neg && !y.neg // -0 - +0 == -0
- return z
- }
-
- if x.form == inf || y.form == zero {
- // ±Inf - y
- // x - ±0
- return z.Set(x)
- }
-
- // ±0 - y
- // x - ±Inf
- return z.Neg(y)
-}
-
-// Mul sets z to the rounded product x*y and returns z.
-// Precision, rounding, and accuracy reporting are as for Add.
-// Mul panics with ErrNaN if one operand is zero and the other
-// operand an infinity. The value of z is undefined in that case.
-func (z *Float) Mul(x, y *Float) *Float {
- if debugFloat {
- x.validate()
- y.validate()
- }
-
- if z.prec == 0 {
- z.prec = umax32(x.prec, y.prec)
- }
-
- z.neg = x.neg != y.neg
-
- if x.form == finite && y.form == finite {
- // x * y (common case)
- z.umul(x, y)
- return z
- }
-
- z.acc = Exact
- if x.form == zero && y.form == inf || x.form == inf && y.form == zero {
- // ±0 * ±Inf
- // ±Inf * ±0
- // value of z is undefined but make sure it's valid
- z.form = zero
- z.neg = false
- panic(ErrNaN{"multiplication of zero with infinity"})
- }
-
- if x.form == inf || y.form == inf {
- // ±Inf * y
- // x * ±Inf
- z.form = inf
- return z
- }
-
- // ±0 * y
- // x * ±0
- z.form = zero
- return z
-}
-
-// Quo sets z to the rounded quotient x/y and returns z.
-// Precision, rounding, and accuracy reporting are as for Add.
-// Quo panics with ErrNaN if both operands are zero or infinities.
-// The value of z is undefined in that case.
-func (z *Float) Quo(x, y *Float) *Float {
- if debugFloat {
- x.validate()
- y.validate()
- }
-
- if z.prec == 0 {
- z.prec = umax32(x.prec, y.prec)
- }
-
- z.neg = x.neg != y.neg
-
- if x.form == finite && y.form == finite {
- // x / y (common case)
- z.uquo(x, y)
- return z
- }
-
- z.acc = Exact
- if x.form == zero && y.form == zero || x.form == inf && y.form == inf {
- // ±0 / ±0
- // ±Inf / ±Inf
- // value of z is undefined but make sure it's valid
- z.form = zero
- z.neg = false
- panic(ErrNaN{"division of zero by zero or infinity by infinity"})
- }
-
- if x.form == zero || y.form == inf {
- // ±0 / y
- // x / ±Inf
- z.form = zero
- return z
- }
-
- // x / ±0
- // ±Inf / y
- z.form = inf
- return z
-}
-
-// Cmp compares x and y and returns:
-//
-// -1 if x < y
-// 0 if x == y (incl. -0 == 0, -Inf == -Inf, and +Inf == +Inf)
-// +1 if x > y
-//
-func (x *Float) Cmp(y *Float) int {
- if debugFloat {
- x.validate()
- y.validate()
- }
-
- mx := x.ord()
- my := y.ord()
- switch {
- case mx < my:
- return -1
- case mx > my:
- return +1
- }
- // mx == my
-
- // only if |mx| == 1 we have to compare the mantissae
- switch mx {
- case -1:
- return y.ucmp(x)
- case +1:
- return x.ucmp(y)
- }
-
- return 0
-}
-
-// ord classifies x and returns:
-//
-// -2 if -Inf == x
-// -1 if -Inf < x < 0
-// 0 if x == 0 (signed or unsigned)
-// +1 if 0 < x < +Inf
-// +2 if x == +Inf
-//
-func (x *Float) ord() int {
- var m int
- switch x.form {
- case finite:
- m = 1
- case zero:
- return 0
- case inf:
- m = 2
- }
- if x.neg {
- m = -m
- }
- return m
-}
-
-func umax32(x, y uint32) uint32 {
- if x > y {
- return x
- }
- return y
-}
diff --git a/src/cmd/compile/internal/big/float_test.go b/src/cmd/compile/internal/big/float_test.go
deleted file mode 100644
index 464619b..0000000
--- a/src/cmd/compile/internal/big/float_test.go
+++ /dev/null
@@ -1,1764 +0,0 @@
-// Copyright 2014 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 big
-
-import (
- "fmt"
- "math"
- "strconv"
- "strings"
- "testing"
-)
-
-// Verify that ErrNaN implements the error interface.
-var _ error = ErrNaN{}
-
-func (x *Float) uint64() uint64 {
- u, acc := x.Uint64()
- if acc != Exact {
- panic(fmt.Sprintf("%s is not a uint64", x.Text('g', 10)))
- }
- return u
-}
-
-func (x *Float) int64() int64 {
- i, acc := x.Int64()
- if acc != Exact {
- panic(fmt.Sprintf("%s is not an int64", x.Text('g', 10)))
- }
- return i
-}
-
-func TestFloatZeroValue(t *testing.T) {
- // zero (uninitialized) value is a ready-to-use 0.0
- var x Float
- if s := x.Text('f', 1); s != "0.0" {
- t.Errorf("zero value = %s; want 0.0", s)
- }
-
- // zero value has precision 0
- if prec := x.Prec(); prec != 0 {
- t.Errorf("prec = %d; want 0", prec)
- }
-
- // zero value can be used in any and all positions of binary operations
- make := func(x int) *Float {
- var f Float
- if x != 0 {
- f.SetInt64(int64(x))
- }
- // x == 0 translates into the zero value
- return &f
- }
- for _, test := range []struct {
- z, x, y, want int
- opname rune
- op func(z, x, y *Float) *Float
- }{
- {0, 0, 0, 0, '+', (*Float).Add},
- {0, 1, 2, 3, '+', (*Float).Add},
- {1, 2, 0, 2, '+', (*Float).Add},
- {2, 0, 1, 1, '+', (*Float).Add},
-
- {0, 0, 0, 0, '-', (*Float).Sub},
- {0, 1, 2, -1, '-', (*Float).Sub},
- {1, 2, 0, 2, '-', (*Float).Sub},
- {2, 0, 1, -1, '-', (*Float).Sub},
-
- {0, 0, 0, 0, '*', (*Float).Mul},
- {0, 1, 2, 2, '*', (*Float).Mul},
- {1, 2, 0, 0, '*', (*Float).Mul},
- {2, 0, 1, 0, '*', (*Float).Mul},
-
- // {0, 0, 0, 0, '/', (*Float).Quo}, // panics
- {0, 2, 1, 2, '/', (*Float).Quo},
- {1, 2, 0, 0, '/', (*Float).Quo}, // = +Inf
- {2, 0, 1, 0, '/', (*Float).Quo},
- } {
- z := make(test.z)
- test.op(z, make(test.x), make(test.y))
- got := 0
- if !z.IsInf() {
- got = int(z.int64())
- }
- if got != test.want {
- t.Errorf("%d %c %d = %d; want %d", test.x, test.opname, test.y, got, test.want)
- }
- }
-
- // TODO(gri) test how precision is set for zero value results
-}
-
-func makeFloat(s string) *Float {
- x, _, err := ParseFloat(s, 0, 1000, ToNearestEven)
- if err != nil {
- panic(err)
- }
- return x
-}
-
-func TestFloatSetPrec(t *testing.T) {
- for _, test := range []struct {
- x string
- prec uint
- want string
- acc Accuracy
- }{
- // prec 0
- {"0", 0, "0", Exact},
- {"-0", 0, "-0", Exact},
- {"-Inf", 0, "-Inf", Exact},
- {"+Inf", 0, "+Inf", Exact},
- {"123", 0, "0", Below},
- {"-123", 0, "-0", Above},
-
- // prec at upper limit
- {"0", MaxPrec, "0", Exact},
- {"-0", MaxPrec, "-0", Exact},
- {"-Inf", MaxPrec, "-Inf", Exact},
- {"+Inf", MaxPrec, "+Inf", Exact},
-
- // just a few regular cases - general rounding is tested elsewhere
- {"1.5", 1, "2", Above},
- {"-1.5", 1, "-2", Below},
- {"123", 1e6, "123", Exact},
- {"-123", 1e6, "-123", Exact},
- } {
- x := makeFloat(test.x).SetPrec(test.prec)
- prec := test.prec
- if prec > MaxPrec {
- prec = MaxPrec
- }
- if got := x.Prec(); got != prec {
- t.Errorf("%s.SetPrec(%d).Prec() == %d; want %d", test.x, test.prec, got, prec)
- }
- if got, acc := x.String(), x.Acc(); got != test.want || acc != test.acc {
- t.Errorf("%s.SetPrec(%d) = %s (%s); want %s (%s)", test.x, test.prec, got, acc, test.want, test.acc)
- }
- }
-}
-
-func TestFloatMinPrec(t *testing.T) {
- const max = 100
- for _, test := range []struct {
- x string
- want uint
- }{
- {"0", 0},
- {"-0", 0},
- {"+Inf", 0},
- {"-Inf", 0},
- {"1", 1},
- {"2", 1},
- {"3", 2},
- {"0x8001", 16},
- {"0x8001p-1000", 16},
- {"0x8001p+1000", 16},
- {"0.1", max},
- } {
- x := makeFloat(test.x).SetPrec(max)
- if got := x.MinPrec(); got != test.want {
- t.Errorf("%s.MinPrec() = %d; want %d", test.x, got, test.want)
- }
- }
-}
-
-func TestFloatSign(t *testing.T) {
- for _, test := range []struct {
- x string
- s int
- }{
- {"-Inf", -1},
- {"-1", -1},
- {"-0", 0},
- {"+0", 0},
- {"+1", +1},
- {"+Inf", +1},
- } {
- x := makeFloat(test.x)
- s := x.Sign()
- if s != test.s {
- t.Errorf("%s.Sign() = %d; want %d", test.x, s, test.s)
- }
- }
-}
-
-// alike(x, y) is like x.Cmp(y) == 0 but also considers the sign of 0 (0 != -0).
-func alike(x, y *Float) bool {
- return x.Cmp(y) == 0 && x.Signbit() == y.Signbit()
-}
-
-func alike32(x, y float32) bool {
- // we can ignore NaNs
- return x == y && math.Signbit(float64(x)) == math.Signbit(float64(y))
-
-}
-
-func alike64(x, y float64) bool {
- // we can ignore NaNs
- return x == y && math.Signbit(x) == math.Signbit(y)
-
-}
-
-func TestFloatMantExp(t *testing.T) {
- for _, test := range []struct {
- x string
- mant string
- exp int
- }{
- {"0", "0", 0},
- {"+0", "0", 0},
- {"-0", "-0", 0},
- {"Inf", "+Inf", 0},
- {"+Inf", "+Inf", 0},
- {"-Inf", "-Inf", 0},
- {"1.5", "0.75", 1},
- {"1.024e3", "0.5", 11},
- {"-0.125", "-0.5", -2},
- } {
- x := makeFloat(test.x)
- mant := makeFloat(test.mant)
- m := new(Float)
- e := x.MantExp(m)
- if !alike(m, mant) || e != test.exp {
- t.Errorf("%s.MantExp() = %s, %d; want %s, %d", test.x, m.Text('g', 10), e, test.mant, test.exp)
- }
- }
-}
-
-func TestFloatMantExpAliasing(t *testing.T) {
- x := makeFloat("0.5p10")
- if e := x.MantExp(x); e != 10 {
- t.Fatalf("Float.MantExp aliasing error: got %d; want 10", e)
- }
- if want := makeFloat("0.5"); !alike(x, want) {
- t.Fatalf("Float.MantExp aliasing error: got %s; want %s", x.Text('g', 10), want.Text('g', 10))
- }
-}
-
-func TestFloatSetMantExp(t *testing.T) {
- for _, test := range []struct {
- frac string
- exp int
- z string
- }{
- {"0", 0, "0"},
- {"+0", 0, "0"},
- {"-0", 0, "-0"},
- {"Inf", 1234, "+Inf"},
- {"+Inf", -1234, "+Inf"},
- {"-Inf", -1234, "-Inf"},
- {"0", MinExp, "0"},
- {"0.25", MinExp, "+0"}, // exponent underflow
- {"-0.25", MinExp, "-0"}, // exponent underflow
- {"1", MaxExp, "+Inf"}, // exponent overflow
- {"2", MaxExp - 1, "+Inf"}, // exponent overflow
- {"0.75", 1, "1.5"},
- {"0.5", 11, "1024"},
- {"-0.5", -2, "-0.125"},
- {"32", 5, "1024"},
- {"1024", -10, "1"},
- } {
- frac := makeFloat(test.frac)
- want := makeFloat(test.z)
- var z Float
- z.SetMantExp(frac, test.exp)
- if !alike(&z, want) {
- t.Errorf("SetMantExp(%s, %d) = %s; want %s", test.frac, test.exp, z.Text('g', 10), test.z)
- }
- // test inverse property
- mant := new(Float)
- if z.SetMantExp(mant, want.MantExp(mant)).Cmp(want) != 0 {
- t.Errorf("Inverse property not satisfied: got %s; want %s", z.Text('g', 10), test.z)
- }
- }
-}
-
-func TestFloatPredicates(t *testing.T) {
- for _, test := range []struct {
- x string
- sign int
- signbit, inf bool
- }{
- {x: "-Inf", sign: -1, signbit: true, inf: true},
- {x: "-1", sign: -1, signbit: true},
- {x: "-0", signbit: true},
- {x: "0"},
- {x: "1", sign: 1},
- {x: "+Inf", sign: 1, inf: true},
- } {
- x := makeFloat(test.x)
- if got := x.Signbit(); got != test.signbit {
- t.Errorf("(%s).Signbit() = %v; want %v", test.x, got, test.signbit)
- }
- if got := x.Sign(); got != test.sign {
- t.Errorf("(%s).Sign() = %d; want %d", test.x, got, test.sign)
- }
- if got := x.IsInf(); got != test.inf {
- t.Errorf("(%s).IsInf() = %v; want %v", test.x, got, test.inf)
- }
- }
-}
-
-func TestFloatIsInt(t *testing.T) {
- for _, test := range []string{
- "0 int",
- "-0 int",
- "1 int",
- "-1 int",
- "0.5",
- "1.23",
- "1.23e1",
- "1.23e2 int",
- "0.000000001e+8",
- "0.000000001e+9 int",
- "1.2345e200 int",
- "Inf",
- "+Inf",
- "-Inf",
- } {
- s := strings.TrimSuffix(test, " int")
- want := s != test
- if got := makeFloat(s).IsInt(); got != want {
- t.Errorf("%s.IsInt() == %t", s, got)
- }
- }
-}
-
-func fromBinary(s string) int64 {
- x, err := strconv.ParseInt(s, 2, 64)
- if err != nil {
- panic(err)
- }
- return x
-}
-
-func toBinary(x int64) string {
- return strconv.FormatInt(x, 2)
-}
-
-func testFloatRound(t *testing.T, x, r int64, prec uint, mode RoundingMode) {
- // verify test data
- var ok bool
- switch mode {
- case ToNearestEven, ToNearestAway:
- ok = true // nothing to do for now
- case ToZero:
- if x < 0 {
- ok = r >= x
- } else {
- ok = r <= x
- }
- case AwayFromZero:
- if x < 0 {
- ok = r <= x
- } else {
- ok = r >= x
- }
- case ToNegativeInf:
- ok = r <= x
- case ToPositiveInf:
- ok = r >= x
- default:
- panic("unreachable")
- }
- if !ok {
- t.Fatalf("incorrect test data for prec = %d, %s: x = %s, r = %s", prec, mode, toBinary(x), toBinary(r))
- }
-
- // compute expected accuracy
- a := Exact
- switch {
- case r < x:
- a = Below
- case r > x:
- a = Above
- }
-
- // round
- f := new(Float).SetMode(mode).SetInt64(x).SetPrec(prec)
-
- // check result
- r1 := f.int64()
- p1 := f.Prec()
- a1 := f.Acc()
- if r1 != r || p1 != prec || a1 != a {
- t.Errorf("round %s (%d bits, %s) incorrect: got %s (%d bits, %s); want %s (%d bits, %s)",
- toBinary(x), prec, mode,
- toBinary(r1), p1, a1,
- toBinary(r), prec, a)
- return
- }
-
- // g and f should be the same
- // (rounding by SetPrec after SetInt64 using default precision
- // should be the same as rounding by SetInt64 after setting the
- // precision)
- g := new(Float).SetMode(mode).SetPrec(prec).SetInt64(x)
- if !alike(g, f) {
- t.Errorf("round %s (%d bits, %s) not symmetric: got %s and %s; want %s",
- toBinary(x), prec, mode,
- toBinary(g.int64()),
- toBinary(r1),
- toBinary(r),
- )
- return
- }
-
- // h and f should be the same
- // (repeated rounding should be idempotent)
- h := new(Float).SetMode(mode).SetPrec(prec).Set(f)
- if !alike(h, f) {
- t.Errorf("round %s (%d bits, %s) not idempotent: got %s and %s; want %s",
- toBinary(x), prec, mode,
- toBinary(h.int64()),
- toBinary(r1),
- toBinary(r),
- )
- return
- }
-}
-
-// TestFloatRound tests basic rounding.
-func TestFloatRound(t *testing.T) {
- for _, test := range []struct {
- prec uint
- x, zero, neven, naway, away string // input, results rounded to prec bits
- }{
- {5, "1000", "1000", "1000", "1000", "1000"},
- {5, "1001", "1001", "1001", "1001", "1001"},
- {5, "1010", "1010", "1010", "1010", "1010"},
- {5, "1011", "1011", "1011", "1011", "1011"},
- {5, "1100", "1100", "1100", "1100", "1100"},
- {5, "1101", "1101", "1101", "1101", "1101"},
- {5, "1110", "1110", "1110", "1110", "1110"},
- {5, "1111", "1111", "1111", "1111", "1111"},
-
- {4, "1000", "1000", "1000", "1000", "1000"},
- {4, "1001", "1001", "1001", "1001", "1001"},
- {4, "1010", "1010", "1010", "1010", "1010"},
- {4, "1011", "1011", "1011", "1011", "1011"},
- {4, "1100", "1100", "1100", "1100", "1100"},
- {4, "1101", "1101", "1101", "1101", "1101"},
- {4, "1110", "1110", "1110", "1110", "1110"},
- {4, "1111", "1111", "1111", "1111", "1111"},
-
- {3, "1000", "1000", "1000", "1000", "1000"},
- {3, "1001", "1000", "1000", "1010", "1010"},
- {3, "1010", "1010", "1010", "1010", "1010"},
- {3, "1011", "1010", "1100", "1100", "1100"},
- {3, "1100", "1100", "1100", "1100", "1100"},
- {3, "1101", "1100", "1100", "1110", "1110"},
- {3, "1110", "1110", "1110", "1110", "1110"},
- {3, "1111", "1110", "10000", "10000", "10000"},
-
- {3, "1000001", "1000000", "1000000", "1000000", "1010000"},
- {3, "1001001", "1000000", "1010000", "1010000", "1010000"},
- {3, "1010001", "1010000", "1010000", "1010000", "1100000"},
- {3, "1011001", "1010000", "1100000", "1100000", "1100000"},
- {3, "1100001", "1100000", "1100000", "1100000", "1110000"},
- {3, "1101001", "1100000", "1110000", "1110000", "1110000"},
- {3, "1110001", "1110000", "1110000", "1110000", "10000000"},
- {3, "1111001", "1110000", "10000000", "10000000", "10000000"},
-
- {2, "1000", "1000", "1000", "1000", "1000"},
- {2, "1001", "1000", "1000", "1000", "1100"},
- {2, "1010", "1000", "1000", "1100", "1100"},
- {2, "1011", "1000", "1100", "1100", "1100"},
- {2, "1100", "1100", "1100", "1100", "1100"},
- {2, "1101", "1100", "1100", "1100", "10000"},
- {2, "1110", "1100", "10000", "10000", "10000"},
- {2, "1111", "1100", "10000", "10000", "10000"},
-
- {2, "1000001", "1000000", "1000000", "1000000", "1100000"},
- {2, "1001001", "1000000", "1000000", "1000000", "1100000"},
- {2, "1010001", "1000000", "1100000", "1100000", "1100000"},
- {2, "1011001", "1000000", "1100000", "1100000", "1100000"},
- {2, "1100001", "1100000", "1100000", "1100000", "10000000"},
- {2, "1101001", "1100000", "1100000", "1100000", "10000000"},
- {2, "1110001", "1100000", "10000000", "10000000", "10000000"},
- {2, "1111001", "1100000", "10000000", "10000000", "10000000"},
-
- {1, "1000", "1000", "1000", "1000", "1000"},
- {1, "1001", "1000", "1000", "1000", "10000"},
- {1, "1010", "1000", "1000", "1000", "10000"},
- {1, "1011", "1000", "1000", "1000", "10000"},
- {1, "1100", "1000", "10000", "10000", "10000"},
- {1, "1101", "1000", "10000", "10000", "10000"},
- {1, "1110", "1000", "10000", "10000", "10000"},
- {1, "1111", "1000", "10000", "10000", "10000"},
-
- {1, "1000001", "1000000", "1000000", "1000000", "10000000"},
- {1, "1001001", "1000000", "1000000", "1000000", "10000000"},
- {1, "1010001", "1000000", "1000000", "1000000", "10000000"},
- {1, "1011001", "1000000", "1000000", "1000000", "10000000"},
- {1, "1100001", "1000000", "10000000", "10000000", "10000000"},
- {1, "1101001", "1000000", "10000000", "10000000", "10000000"},
- {1, "1110001", "1000000", "10000000", "10000000", "10000000"},
- {1, "1111001", "1000000", "10000000", "10000000", "10000000"},
- } {
- x := fromBinary(test.x)
- z := fromBinary(test.zero)
- e := fromBinary(test.neven)
- n := fromBinary(test.naway)
- a := fromBinary(test.away)
- prec := test.prec
-
- testFloatRound(t, x, z, prec, ToZero)
- testFloatRound(t, x, e, prec, ToNearestEven)
- testFloatRound(t, x, n, prec, ToNearestAway)
- testFloatRound(t, x, a, prec, AwayFromZero)
-
- testFloatRound(t, x, z, prec, ToNegativeInf)
- testFloatRound(t, x, a, prec, ToPositiveInf)
-
- testFloatRound(t, -x, -a, prec, ToNegativeInf)
- testFloatRound(t, -x, -z, prec, ToPositiveInf)
- }
-}
-
-// TestFloatRound24 tests that rounding a float64 to 24 bits
-// matches IEEE-754 rounding to nearest when converting a
-// float64 to a float32 (excluding denormal numbers).
-func TestFloatRound24(t *testing.T) {
- const x0 = 1<<26 - 0x10 // 11...110000 (26 bits)
- for d := 0; d <= 0x10; d++ {
- x := float64(x0 + d)
- f := new(Float).SetPrec(24).SetFloat64(x)
- got, _ := f.Float32()
- want := float32(x)
- if got != want {
- t.Errorf("Round(%g, 24) = %g; want %g", x, got, want)
- }
- }
-}
-
-func TestFloatSetUint64(t *testing.T) {
- for _, want := range []uint64{
- 0,
- 1,
- 2,
- 10,
- 100,
- 1<<32 - 1,
- 1 << 32,
- 1<<64 - 1,
- } {
- var f Float
- f.SetUint64(want)
- if got := f.uint64(); got != want {
- t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want)
- }
- }
-
- // test basic rounding behavior (exhaustive rounding testing is done elsewhere)
- const x uint64 = 0x8765432187654321 // 64 bits needed
- for prec := uint(1); prec <= 64; prec++ {
- f := new(Float).SetPrec(prec).SetMode(ToZero).SetUint64(x)
- got := f.uint64()
- want := x &^ (1<<(64-prec) - 1) // cut off (round to zero) low 64-prec bits
- if got != want {
- t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want)
- }
- }
-}
-
-func TestFloatSetInt64(t *testing.T) {
- for _, want := range []int64{
- 0,
- 1,
- 2,
- 10,
- 100,
- 1<<32 - 1,
- 1 << 32,
- 1<<63 - 1,
- } {
- for i := range [2]int{} {
- if i&1 != 0 {
- want = -want
- }
- var f Float
- f.SetInt64(want)
- if got := f.int64(); got != want {
- t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want)
- }
- }
- }
-
- // test basic rounding behavior (exhaustive rounding testing is done elsewhere)
- const x int64 = 0x7654321076543210 // 63 bits needed
- for prec := uint(1); prec <= 63; prec++ {
- f := new(Float).SetPrec(prec).SetMode(ToZero).SetInt64(x)
- got := f.int64()
- want := x &^ (1<<(63-prec) - 1) // cut off (round to zero) low 63-prec bits
- if got != want {
- t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want)
- }
- }
-}
-
-func TestFloatSetFloat64(t *testing.T) {
- for _, want := range []float64{
- 0,
- 1,
- 2,
- 12345,
- 1e10,
- 1e100,
- 3.14159265e10,
- 2.718281828e-123,
- 1.0 / 3,
- math.MaxFloat32,
- math.MaxFloat64,
- math.SmallestNonzeroFloat32,
- math.SmallestNonzeroFloat64,
- math.Inf(-1),
- math.Inf(0),
- -math.Inf(1),
- } {
- for i := range [2]int{} {
- if i&1 != 0 {
- want = -want
- }
- var f Float
- f.SetFloat64(want)
- if got, acc := f.Float64(); got != want || acc != Exact {
- t.Errorf("got %g (%s, %s); want %g (Exact)", got, f.Text('p', 0), acc, want)
- }
- }
- }
-
- // test basic rounding behavior (exhaustive rounding testing is done elsewhere)
- const x uint64 = 0x8765432143218 // 53 bits needed
- for prec := uint(1); prec <= 52; prec++ {
- f := new(Float).SetPrec(prec).SetMode(ToZero).SetFloat64(float64(x))
- got, _ := f.Float64()
- want := float64(x &^ (1<<(52-prec) - 1)) // cut off (round to zero) low 53-prec bits
- if got != want {
- t.Errorf("got %g (%s); want %g", got, f.Text('p', 0), want)
- }
- }
-
- // test NaN
- defer func() {
- if p, ok := recover().(ErrNaN); !ok {
- t.Errorf("got %v; want ErrNaN panic", p)
- }
- }()
- var f Float
- f.SetFloat64(math.NaN())
- // should not reach here
- t.Errorf("got %s; want ErrNaN panic", f.Text('p', 0))
-}
-
-func TestFloatSetInt(t *testing.T) {
- for _, want := range []string{
- "0",
- "1",
- "-1",
- "1234567890",
- "123456789012345678901234567890",
- "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
- } {
- var x Int
- _, ok := x.SetString(want, 0)
- if !ok {
- t.Errorf("invalid integer %s", want)
- continue
- }
- n := x.BitLen()
-
- var f Float
- f.SetInt(&x)
-
- // check precision
- if n < 64 {
- n = 64
- }
- if prec := f.Prec(); prec != uint(n) {
- t.Errorf("got prec = %d; want %d", prec, n)
- }
-
- // check value
- got := f.Text('g', 100)
- if got != want {
- t.Errorf("got %s (%s); want %s", got, f.Text('p', 0), want)
- }
- }
-
- // TODO(gri) test basic rounding behavior
-}
-
-func TestFloatSetRat(t *testing.T) {
- for _, want := range []string{
- "0",
- "1",
- "-1",
- "1234567890",
- "123456789012345678901234567890",
- "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
- "1.2",
- "3.14159265",
- // TODO(gri) expand
- } {
- var x Rat
- _, ok := x.SetString(want)
- if !ok {
- t.Errorf("invalid fraction %s", want)
- continue
- }
- n := max(x.Num().BitLen(), x.Denom().BitLen())
-
- var f1, f2 Float
- f2.SetPrec(1000)
- f1.SetRat(&x)
- f2.SetRat(&x)
-
- // check precision when set automatically
- if n < 64 {
- n = 64
- }
- if prec := f1.Prec(); prec != uint(n) {
- t.Errorf("got prec = %d; want %d", prec, n)
- }
-
- got := f2.Text('g', 100)
- if got != want {
- t.Errorf("got %s (%s); want %s", got, f2.Text('p', 0), want)
- }
- }
-}
-
-func TestFloatSetInf(t *testing.T) {
- var f Float
- for _, test := range []struct {
- signbit bool
- prec uint
- want string
- }{
- {false, 0, "+Inf"},
- {true, 0, "-Inf"},
- {false, 10, "+Inf"},
- {true, 30, "-Inf"},
- } {
- x := f.SetPrec(test.prec).SetInf(test.signbit)
- if got := x.String(); got != test.want || x.Prec() != test.prec {
- t.Errorf("SetInf(%v) = %s (prec = %d); want %s (prec = %d)", test.signbit, got, x.Prec(), test.want, test.prec)
- }
- }
-}
-
-func TestFloatUint64(t *testing.T) {
- for _, test := range []struct {
- x string
- out uint64
- acc Accuracy
- }{
- {"-Inf", 0, Above},
- {"-1", 0, Above},
- {"-1e-1000", 0, Above},
- {"-0", 0, Exact},
- {"0", 0, Exact},
- {"1e-1000", 0, Below},
- {"1", 1, Exact},
- {"1.000000000000000000001", 1, Below},
- {"12345.0", 12345, Exact},
- {"12345.000000000000000000001", 12345, Below},
- {"18446744073709551615", 18446744073709551615, Exact},
- {"18446744073709551615.000000000000000000001", math.MaxUint64, Below},
- {"18446744073709551616", math.MaxUint64, Below},
- {"1e10000", math.MaxUint64, Below},
- {"+Inf", math.MaxUint64, Below},
- } {
- x := makeFloat(test.x)
- out, acc := x.Uint64()
- if out != test.out || acc != test.acc {
- t.Errorf("%s: got %d (%s); want %d (%s)", test.x, out, acc, test.out, test.acc)
- }
- }
-}
-
-func TestFloatInt64(t *testing.T) {
- for _, test := range []struct {
- x string
- out int64
- acc Accuracy
- }{
- {"-Inf", math.MinInt64, Above},
- {"-1e10000", math.MinInt64, Above},
- {"-9223372036854775809", math.MinInt64, Above},
- {"-9223372036854775808.000000000000000000001", math.MinInt64, Above},
- {"-9223372036854775808", -9223372036854775808, Exact},
- {"-9223372036854775807.000000000000000000001", -9223372036854775807, Above},
- {"-9223372036854775807", -9223372036854775807, Exact},
- {"-12345.000000000000000000001", -12345, Above},
- {"-12345.0", -12345, Exact},
- {"-1.000000000000000000001", -1, Above},
- {"-1.5", -1, Above},
- {"-1", -1, Exact},
- {"-1e-1000", 0, Above},
- {"0", 0, Exact},
- {"1e-1000", 0, Below},
- {"1", 1, Exact},
- {"1.000000000000000000001", 1, Below},
- {"1.5", 1, Below},
- {"12345.0", 12345, Exact},
- {"12345.000000000000000000001", 12345, Below},
- {"9223372036854775807", 9223372036854775807, Exact},
- {"9223372036854775807.000000000000000000001", math.MaxInt64, Below},
- {"9223372036854775808", math.MaxInt64, Below},
- {"1e10000", math.MaxInt64, Below},
- {"+Inf", math.MaxInt64, Below},
- } {
- x := makeFloat(test.x)
- out, acc := x.Int64()
- if out != test.out || acc != test.acc {
- t.Errorf("%s: got %d (%s); want %d (%s)", test.x, out, acc, test.out, test.acc)
- }
- }
-}
-
-func TestFloatFloat32(t *testing.T) {
- for _, test := range []struct {
- x string
- out float32
- acc Accuracy
- }{
- {"0", 0, Exact},
-
- // underflow to zero
- {"1e-1000", 0, Below},
- {"0x0.000002p-127", 0, Below},
- {"0x.0000010p-126", 0, Below},
-
- // denormals
- {"1.401298464e-45", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
- {"0x.ffffff8p-149", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
- {"0x.0000018p-126", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
- {"0x.0000020p-126", math.SmallestNonzeroFloat32, Exact},
- {"0x.8p-148", math.SmallestNonzeroFloat32, Exact},
- {"1p-149", math.SmallestNonzeroFloat32, Exact},
- {"0x.fffffep-126", math.Float32frombits(0x7fffff), Exact}, // largest denormal
-
- // special denormal cases (see issues 14553, 14651)
- {"0x0.0000001p-126", math.Float32frombits(0x00000000), Below}, // underflow to zero
- {"0x0.0000008p-126", math.Float32frombits(0x00000000), Below}, // underflow to zero
- {"0x0.0000010p-126", math.Float32frombits(0x00000000), Below}, // rounded down to even
- {"0x0.0000011p-126", math.Float32frombits(0x00000001), Above}, // rounded up to smallest denormal
- {"0x0.0000018p-126", math.Float32frombits(0x00000001), Above}, // rounded up to smallest denormal
-
- {"0x1.0000000p-149", math.Float32frombits(0x00000001), Exact}, // smallest denormal
- {"0x0.0000020p-126", math.Float32frombits(0x00000001), Exact}, // smallest denormal
- {"0x0.fffffe0p-126", math.Float32frombits(0x007fffff), Exact}, // largest denormal
- {"0x1.0000000p-126", math.Float32frombits(0x00800000), Exact}, // smallest normal
-
- {"0x0.8p-149", math.Float32frombits(0x000000000), Below}, // rounded down to even
- {"0x0.9p-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal
- {"0x0.ap-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal
- {"0x0.bp-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal
- {"0x0.cp-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal
-
- {"0x1.0p-149", math.Float32frombits(0x000000001), Exact}, // smallest denormal
- {"0x1.7p-149", math.Float32frombits(0x000000001), Below},
- {"0x1.8p-149", math.Float32frombits(0x000000002), Above},
- {"0x1.9p-149", math.Float32frombits(0x000000002), Above},
-
- {"0x2.0p-149", math.Float32frombits(0x000000002), Exact},
- {"0x2.8p-149", math.Float32frombits(0x000000002), Below}, // rounded down to even
- {"0x2.9p-149", math.Float32frombits(0x000000003), Above},
-
- {"0x3.0p-149", math.Float32frombits(0x000000003), Exact},
- {"0x3.7p-149", math.Float32frombits(0x000000003), Below},
- {"0x3.8p-149", math.Float32frombits(0x000000004), Above}, // rounded up to even
-
- {"0x4.0p-149", math.Float32frombits(0x000000004), Exact},
- {"0x4.8p-149", math.Float32frombits(0x000000004), Below}, // rounded down to even
- {"0x4.9p-149", math.Float32frombits(0x000000005), Above},
-
- // specific case from issue 14553
- {"0x7.7p-149", math.Float32frombits(0x000000007), Below},
- {"0x7.8p-149", math.Float32frombits(0x000000008), Above},
- {"0x7.9p-149", math.Float32frombits(0x000000008), Above},
-
- // normals
- {"0x.ffffffp-126", math.Float32frombits(0x00800000), Above}, // rounded up to smallest normal
- {"1p-126", math.Float32frombits(0x00800000), Exact}, // smallest normal
- {"0x1.fffffep-126", math.Float32frombits(0x00ffffff), Exact},
- {"0x1.ffffffp-126", math.Float32frombits(0x01000000), Above}, // rounded up
- {"1", 1, Exact},
- {"1.000000000000000000001", 1, Below},
- {"12345.0", 12345, Exact},
- {"12345.000000000000000000001", 12345, Below},
- {"0x1.fffffe0p127", math.MaxFloat32, Exact},
- {"0x1.fffffe8p127", math.MaxFloat32, Below},
-
- // overflow
- {"0x1.ffffff0p127", float32(math.Inf(+1)), Above},
- {"0x1p128", float32(math.Inf(+1)), Above},
- {"1e10000", float32(math.Inf(+1)), Above},
- {"0x1.ffffff0p2147483646", float32(math.Inf(+1)), Above}, // overflow in rounding
-
- // inf
- {"Inf", float32(math.Inf(+1)), Exact},
- } {
- for i := 0; i < 2; i++ {
- // test both signs
- tx, tout, tacc := test.x, test.out, test.acc
- if i != 0 {
- tx = "-" + tx
- tout = -tout
- tacc = -tacc
- }
-
- // conversion should match strconv where syntax is agreeable
- if f, err := strconv.ParseFloat(tx, 32); err == nil && !alike32(float32(f), tout) {
- t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout)
- }
-
- x := makeFloat(tx)
- out, acc := x.Float32()
- if !alike32(out, tout) || acc != tacc {
- t.Errorf("%s: got %g (%#08x, %s); want %g (%#08x, %s)", tx, out, math.Float32bits(out), acc, test.out, math.Float32bits(test.out), tacc)
- }
-
- // test that x.SetFloat64(float64(f)).Float32() == f
- var x2 Float
- out2, acc2 := x2.SetFloat64(float64(out)).Float32()
- if !alike32(out2, out) || acc2 != Exact {
- t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out)
- }
- }
- }
-}
-
-func TestFloatFloat64(t *testing.T) {
- const smallestNormalFloat64 = 2.2250738585072014e-308 // 1p-1022
- for _, test := range []struct {
- x string
- out float64
- acc Accuracy
- }{
- {"0", 0, Exact},
-
- // underflow to zero
- {"1e-1000", 0, Below},
- {"0x0.0000000000001p-1023", 0, Below},
- {"0x0.00000000000008p-1022", 0, Below},
-
- // denormals
- {"0x0.0000000000000cp-1022", math.SmallestNonzeroFloat64, Above}, // rounded up to smallest denormal
- {"0x0.00000000000010p-1022", math.SmallestNonzeroFloat64, Exact}, // smallest denormal
- {"0x.8p-1073", math.SmallestNonzeroFloat64, Exact},
- {"1p-1074", math.SmallestNonzeroFloat64, Exact},
- {"0x.fffffffffffffp-1022", math.Float64frombits(0x000fffffffffffff), Exact}, // largest denormal
-
- // special denormal cases (see issues 14553, 14651)
- {"0x0.00000000000001p-1022", math.Float64frombits(0x00000000000000000), Below}, // underflow to zero
- {"0x0.00000000000004p-1022", math.Float64frombits(0x00000000000000000), Below}, // underflow to zero
- {"0x0.00000000000008p-1022", math.Float64frombits(0x00000000000000000), Below}, // rounded down to even
- {"0x0.00000000000009p-1022", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
- {"0x0.0000000000000ap-1022", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
-
- {"0x0.8p-1074", math.Float64frombits(0x00000000000000000), Below}, // rounded down to even
- {"0x0.9p-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
- {"0x0.ap-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
- {"0x0.bp-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
- {"0x0.cp-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
-
- {"0x1.0p-1074", math.Float64frombits(0x00000000000000001), Exact},
- {"0x1.7p-1074", math.Float64frombits(0x00000000000000001), Below},
- {"0x1.8p-1074", math.Float64frombits(0x00000000000000002), Above},
- {"0x1.9p-1074", math.Float64frombits(0x00000000000000002), Above},
-
- {"0x2.0p-1074", math.Float64frombits(0x00000000000000002), Exact},
- {"0x2.8p-1074", math.Float64frombits(0x00000000000000002), Below}, // rounded down to even
- {"0x2.9p-1074", math.Float64frombits(0x00000000000000003), Above},
-
- {"0x3.0p-1074", math.Float64frombits(0x00000000000000003), Exact},
- {"0x3.7p-1074", math.Float64frombits(0x00000000000000003), Below},
- {"0x3.8p-1074", math.Float64frombits(0x00000000000000004), Above}, // rounded up to even
-
- {"0x4.0p-1074", math.Float64frombits(0x00000000000000004), Exact},
- {"0x4.8p-1074", math.Float64frombits(0x00000000000000004), Below}, // rounded down to even
- {"0x4.9p-1074", math.Float64frombits(0x00000000000000005), Above},
-
- // normals
- {"0x.fffffffffffff8p-1022", math.Float64frombits(0x0010000000000000), Above}, // rounded up to smallest normal
- {"1p-1022", math.Float64frombits(0x0010000000000000), Exact}, // smallest normal
- {"1", 1, Exact},
- {"1.000000000000000000001", 1, Below},
- {"12345.0", 12345, Exact},
- {"12345.000000000000000000001", 12345, Below},
- {"0x1.fffffffffffff0p1023", math.MaxFloat64, Exact},
- {"0x1.fffffffffffff4p1023", math.MaxFloat64, Below},
-
- // overflow
- {"0x1.fffffffffffff8p1023", math.Inf(+1), Above},
- {"0x1p1024", math.Inf(+1), Above},
- {"1e10000", math.Inf(+1), Above},
- {"0x1.fffffffffffff8p2147483646", math.Inf(+1), Above}, // overflow in rounding
- {"Inf", math.Inf(+1), Exact},
-
- // selected denormalized values that were handled incorrectly in the past
- {"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/
- {"2.2250738585072011e-308", 2.225073858507201e-308, Below},
- // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
- {"2.2250738585072012e-308", 2.2250738585072014e-308, Above},
- } {
- for i := 0; i < 2; i++ {
- // test both signs
- tx, tout, tacc := test.x, test.out, test.acc
- if i != 0 {
- tx = "-" + tx
- tout = -tout
- tacc = -tacc
- }
-
- // conversion should match strconv where syntax is agreeable
- if f, err := strconv.ParseFloat(tx, 64); err == nil && !alike64(f, tout) {
- t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout)
- }
-
- x := makeFloat(tx)
- out, acc := x.Float64()
- if !alike64(out, tout) || acc != tacc {
- t.Errorf("%s: got %g (%#016x, %s); want %g (%#016x, %s)", tx, out, math.Float64bits(out), acc, test.out, math.Float64bits(test.out), tacc)
- }
-
- // test that x.SetFloat64(f).Float64() == f
- var x2 Float
- out2, acc2 := x2.SetFloat64(out).Float64()
- if !alike64(out2, out) || acc2 != Exact {
- t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out)
- }
- }
- }
-}
-
-func TestFloatInt(t *testing.T) {
- for _, test := range []struct {
- x string
- want string
- acc Accuracy
- }{
- {"0", "0", Exact},
- {"+0", "0", Exact},
- {"-0", "0", Exact},
- {"Inf", "nil", Below},
- {"+Inf", "nil", Below},
- {"-Inf", "nil", Above},
- {"1", "1", Exact},
- {"-1", "-1", Exact},
- {"1.23", "1", Below},
- {"-1.23", "-1", Above},
- {"123e-2", "1", Below},
- {"123e-3", "0", Below},
- {"123e-4", "0", Below},
- {"1e-1000", "0", Below},
- {"-1e-1000", "0", Above},
- {"1e+10", "10000000000", Exact},
- {"1e+100", "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", Exact},
- } {
- x := makeFloat(test.x)
- res, acc := x.Int(nil)
- got := "nil"
- if res != nil {
- got = res.String()
- }
- if got != test.want || acc != test.acc {
- t.Errorf("%s: got %s (%s); want %s (%s)", test.x, got, acc, test.want, test.acc)
- }
- }
-
- // check that supplied *Int is used
- for _, f := range []string{"0", "1", "-1", "1234"} {
- x := makeFloat(f)
- i := new(Int)
- if res, _ := x.Int(i); res != i {
- t.Errorf("(%s).Int is not using supplied *Int", f)
- }
- }
-}
-
-func TestFloatRat(t *testing.T) {
- for _, test := range []struct {
- x, want string
- acc Accuracy
- }{
- {"0", "0/1", Exact},
- {"+0", "0/1", Exact},
- {"-0", "0/1", Exact},
- {"Inf", "nil", Below},
- {"+Inf", "nil", Below},
- {"-Inf", "nil", Above},
- {"1", "1/1", Exact},
- {"-1", "-1/1", Exact},
- {"1.25", "5/4", Exact},
- {"-1.25", "-5/4", Exact},
- {"1e10", "10000000000/1", Exact},
- {"1p10", "1024/1", Exact},
- {"-1p-10", "-1/1024", Exact},
- {"3.14159265", "7244019449799623199/2305843009213693952", Exact},
- } {
- x := makeFloat(test.x).SetPrec(64)
- res, acc := x.Rat(nil)
- got := "nil"
- if res != nil {
- got = res.String()
- }
- if got != test.want {
- t.Errorf("%s: got %s; want %s", test.x, got, test.want)
- continue
- }
- if acc != test.acc {
- t.Errorf("%s: got %s; want %s", test.x, acc, test.acc)
- continue
- }
-
- // inverse conversion
- if res != nil {
- got := new(Float).SetPrec(64).SetRat(res)
- if got.Cmp(x) != 0 {
- t.Errorf("%s: got %s; want %s", test.x, got, x)
- }
- }
- }
-
- // check that supplied *Rat is used
- for _, f := range []string{"0", "1", "-1", "1234"} {
- x := makeFloat(f)
- r := new(Rat)
- if res, _ := x.Rat(r); res != r {
- t.Errorf("(%s).Rat is not using supplied *Rat", f)
- }
- }
-}
-
-func TestFloatAbs(t *testing.T) {
- for _, test := range []string{
- "0",
- "1",
- "1234",
- "1.23e-2",
- "1e-1000",
- "1e1000",
- "Inf",
- } {
- p := makeFloat(test)
- a := new(Float).Abs(p)
- if !alike(a, p) {
- t.Errorf("%s: got %s; want %s", test, a.Text('g', 10), test)
- }
-
- n := makeFloat("-" + test)
- a.Abs(n)
- if !alike(a, p) {
- t.Errorf("-%s: got %s; want %s", test, a.Text('g', 10), test)
- }
- }
-}
-
-func TestFloatNeg(t *testing.T) {
- for _, test := range []string{
- "0",
- "1",
- "1234",
- "1.23e-2",
- "1e-1000",
- "1e1000",
- "Inf",
- } {
- p1 := makeFloat(test)
- n1 := makeFloat("-" + test)
- n2 := new(Float).Neg(p1)
- p2 := new(Float).Neg(n2)
- if !alike(n2, n1) {
- t.Errorf("%s: got %s; want %s", test, n2.Text('g', 10), n1.Text('g', 10))
- }
- if !alike(p2, p1) {
- t.Errorf("%s: got %s; want %s", test, p2.Text('g', 10), p1.Text('g', 10))
- }
- }
-}
-
-func TestFloatInc(t *testing.T) {
- const n = 10
- for _, prec := range precList {
- if 1<<prec < n {
- continue // prec must be large enough to hold all numbers from 0 to n
- }
- var x, one Float
- x.SetPrec(prec)
- one.SetInt64(1)
- for i := 0; i < n; i++ {
- x.Add(&x, &one)
- }
- if x.Cmp(new(Float).SetInt64(n)) != 0 {
- t.Errorf("prec = %d: got %s; want %d", prec, &x, n)
- }
- }
-}
-
-// Selected precisions with which to run various tests.
-var precList = [...]uint{1, 2, 5, 8, 10, 16, 23, 24, 32, 50, 53, 64, 100, 128, 500, 511, 512, 513, 1000, 10000}
-
-// Selected bits with which to run various tests.
-// Each entry is a list of bits representing a floating-point number (see fromBits).
-var bitsList = [...]Bits{
- {}, // = 0
- {0}, // = 1
- {1}, // = 2
- {-1}, // = 1/2
- {10}, // = 2**10 == 1024
- {-10}, // = 2**-10 == 1/1024
- {100, 10, 1}, // = 2**100 + 2**10 + 2**1
- {0, -1, -2, -10},
- // TODO(gri) add more test cases
-}
-
-// TestFloatAdd tests Float.Add/Sub by comparing the result of a "manual"
-// addition/subtraction of arguments represented by Bits values with the
-// respective Float addition/subtraction for a variety of precisions
-// and rounding modes.
-func TestFloatAdd(t *testing.T) {
- for _, xbits := range bitsList {
- for _, ybits := range bitsList {
- // exact values
- x := xbits.Float()
- y := ybits.Float()
- zbits := xbits.add(ybits)
- z := zbits.Float()
-
- for i, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
- for _, prec := range precList {
- got := new(Float).SetPrec(prec).SetMode(mode)
- got.Add(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",
- i, prec, mode, x, xbits, y, ybits, got, want)
- }
-
- got.Sub(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",
- i, prec, mode, z, zbits, x, xbits, got, want)
- }
- }
- }
- }
- }
-}
-
-// TestFloatAdd32 tests that Float.Add/Sub of numbers with
-// 24bit mantissa behaves like float32 addition/subtraction
-// (excluding denormal numbers).
-func TestFloatAdd32(t *testing.T) {
- // chose base such that we cross the mantissa precision limit
- const base = 1<<26 - 0x10 // 11...110000 (26 bits)
- for d := 0; d <= 0x10; d++ {
- for i := range [2]int{} {
- x0, y0 := float64(base), float64(d)
- if i&1 != 0 {
- x0, y0 = y0, x0
- }
-
- x := NewFloat(x0)
- y := NewFloat(y0)
- z := new(Float).SetPrec(24)
-
- z.Add(x, y)
- got, acc := z.Float32()
- want := float32(y0) + float32(x0)
- if got != want || acc != Exact {
- t.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d, x0, y0, got, acc, want)
- }
-
- z.Sub(z, y)
- got, acc = z.Float32()
- want = float32(want) - float32(y0)
- if got != want || acc != Exact {
- t.Errorf("d = %d: %g - %g = %g (%s); want %g (Exact)", d, x0+y0, y0, got, acc, want)
- }
- }
- }
-}
-
-// TestFloatAdd64 tests that Float.Add/Sub of numbers with
-// 53bit mantissa behaves like float64 addition/subtraction.
-func TestFloatAdd64(t *testing.T) {
- // chose base such that we cross the mantissa precision limit
- const base = 1<<55 - 0x10 // 11...110000 (55 bits)
- for d := 0; d <= 0x10; d++ {
- for i := range [2]int{} {
- x0, y0 := float64(base), float64(d)
- if i&1 != 0 {
- x0, y0 = y0, x0
- }
-
- x := NewFloat(x0)
- y := NewFloat(y0)
- z := new(Float).SetPrec(53)
-
- z.Add(x, y)
- got, acc := z.Float64()
- want := x0 + y0
- if got != want || acc != Exact {
- t.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d, x0, y0, got, acc, want)
- }
-
- z.Sub(z, y)
- got, acc = z.Float64()
- want -= y0
- if got != want || acc != Exact {
- t.Errorf("d = %d: %g - %g = %g (%s); want %g (Exact)", d, x0+y0, y0, got, acc, want)
- }
- }
- }
-}
-
-// TestFloatMul tests Float.Mul/Quo by comparing the result of a "manual"
-// multiplication/division of arguments represented by Bits values with the
-// respective Float multiplication/division for a variety of precisions
-// and rounding modes.
-func TestFloatMul(t *testing.T) {
- for _, xbits := range bitsList {
- for _, ybits := range bitsList {
- // exact values
- x := xbits.Float()
- y := ybits.Float()
- zbits := xbits.mul(ybits)
- z := zbits.Float()
-
- for i, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
- for _, prec := range precList {
- got := new(Float).SetPrec(prec).SetMode(mode)
- 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",
- i, prec, mode, x, xbits, y, ybits, got, want)
- }
-
- if x.Sign() == 0 {
- continue // ignore div-0 case (not invertable)
- }
- 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",
- i, prec, mode, z, zbits, x, xbits, got, want)
- }
- }
- }
- }
- }
-}
-
-// TestFloatMul64 tests that Float.Mul/Quo of numbers with
-// 53bit mantissa behaves like float64 multiplication/division.
-func TestFloatMul64(t *testing.T) {
- for _, test := range []struct {
- x, y float64
- }{
- {0, 0},
- {0, 1},
- {1, 1},
- {1, 1.5},
- {1.234, 0.5678},
- {2.718281828, 3.14159265358979},
- {2.718281828e10, 3.14159265358979e-32},
- {1.0 / 3, 1e200},
- } {
- for i := range [8]int{} {
- x0, y0 := test.x, test.y
- if i&1 != 0 {
- x0 = -x0
- }
- if i&2 != 0 {
- y0 = -y0
- }
- if i&4 != 0 {
- x0, y0 = y0, x0
- }
-
- x := NewFloat(x0)
- y := NewFloat(y0)
- z := new(Float).SetPrec(53)
-
- z.Mul(x, y)
- got, _ := z.Float64()
- want := x0 * y0
- if got != want {
- t.Errorf("%g * %g = %g; want %g", x0, y0, got, want)
- }
-
- if y0 == 0 {
- continue // avoid division-by-zero
- }
- z.Quo(z, y)
- got, _ = z.Float64()
- want /= y0
- if got != want {
- t.Errorf("%g / %g = %g; want %g", x0*y0, y0, got, want)
- }
- }
- }
-}
-
-func TestIssue6866(t *testing.T) {
- for _, prec := range precList {
- two := new(Float).SetPrec(prec).SetInt64(2)
- one := new(Float).SetPrec(prec).SetInt64(1)
- three := new(Float).SetPrec(prec).SetInt64(3)
- msix := new(Float).SetPrec(prec).SetInt64(-6)
- psix := new(Float).SetPrec(prec).SetInt64(+6)
-
- p := new(Float).SetPrec(prec)
- z1 := new(Float).SetPrec(prec)
- z2 := new(Float).SetPrec(prec)
-
- // z1 = 2 + 1.0/3*-6
- p.Quo(one, three)
- p.Mul(p, msix)
- z1.Add(two, p)
-
- // z2 = 2 - 1.0/3*+6
- p.Quo(one, three)
- p.Mul(p, psix)
- 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)
- }
- if z1.Sign() != 0 {
- t.Errorf("prec %d: got z1 = %s; want 0", prec, z1)
- }
- if z2.Sign() != 0 {
- t.Errorf("prec %d: got z2 = %s; want 0", prec, z2)
- }
- }
-}
-
-func TestFloatQuo(t *testing.T) {
- // TODO(gri) make the test vary these precisions
- preci := 200 // precision of integer part
- precf := 20 // precision of fractional part
-
- for i := 0; i < 8; i++ {
- // compute accurate (not rounded) result z
- bits := Bits{preci - 1}
- if i&3 != 0 {
- bits = append(bits, 0)
- }
- if i&2 != 0 {
- bits = append(bits, -1)
- }
- if i&1 != 0 {
- bits = append(bits, -precf)
- }
- z := bits.Float()
-
- // compute accurate x as z*y
- y := NewFloat(3.14159265358979323e123)
-
- x := new(Float).SetPrec(z.Prec() + y.Prec()).SetMode(ToZero)
- x.Mul(z, y)
-
- // leave for debugging
- // fmt.Printf("x = %s\ny = %s\nz = %s\n", x, y, z)
-
- if got := x.Acc(); got != Exact {
- t.Errorf("got acc = %s; want exact", got)
- }
-
- // round accurate z for a variety of precisions and
- // modes and compare against result of x / y.
- for _, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
- for d := -5; d < 5; d++ {
- prec := uint(preci + d)
- got := new(Float).SetPrec(prec).SetMode(mode).Quo(x, y)
- want := bits.round(prec, mode)
- if got.Cmp(want) != 0 {
- t.Errorf("i = %d, prec = %d, %s:\n\t %s\n\t/ %s\n\t= %s\n\twant %s",
- i, prec, mode, x, y, got, want)
- }
- }
- }
- }
-}
-
-// TestFloatQuoSmoke tests all divisions x/y for values x, y in the range [-n, +n];
-// it serves as a smoke test for basic correctness of division.
-func TestFloatQuoSmoke(t *testing.T) {
- n := 1000
- if testing.Short() {
- n = 10
- }
-
- const dprec = 3 // max. precision variation
- const prec = 10 + dprec // enough bits to hold n precisely
- for x := -n; x <= n; x++ {
- for y := -n; y < n; y++ {
- if y == 0 {
- continue
- }
-
- a := float64(x)
- b := float64(y)
- c := a / b
-
- // vary operand precision (only ok as long as a, b can be represented correctly)
- for ad := -dprec; ad <= dprec; ad++ {
- for bd := -dprec; bd <= dprec; bd++ {
- A := new(Float).SetPrec(uint(prec + ad)).SetFloat64(a)
- B := new(Float).SetPrec(uint(prec + bd)).SetFloat64(b)
- C := new(Float).SetPrec(53).Quo(A, B) // C has float64 mantissa width
-
- cc, acc := C.Float64()
- if cc != c {
- t.Errorf("%g/%g = %s; want %.5g\n", a, b, C.Text('g', 5), c)
- continue
- }
- if acc != Exact {
- t.Errorf("%g/%g got %s result; want exact result", a, b, acc)
- }
- }
- }
- }
- }
-}
-
-// TestFloatArithmeticSpecialValues tests that Float operations produce the
-// correct results for combinations of zero (±0), finite (±1 and ±2.71828),
-// and infinite (±Inf) operands.
-func TestFloatArithmeticSpecialValues(t *testing.T) {
- zero := 0.0
- args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)}
- xx := new(Float)
- yy := new(Float)
- got := new(Float)
- want := new(Float)
- for i := 0; i < 4; i++ {
- for _, x := range args {
- xx.SetFloat64(x)
- // check conversion is correct
- // (no need to do this for y, since we see exactly the
- // same values there)
- if got, acc := xx.Float64(); got != x || acc != Exact {
- t.Errorf("Float(%g) == %g (%s)", x, got, acc)
- }
- for _, y := range args {
- yy.SetFloat64(y)
- var (
- op string
- z float64
- f func(z, x, y *Float) *Float
- )
- switch i {
- case 0:
- op = "+"
- z = x + y
- f = (*Float).Add
- case 1:
- op = "-"
- z = x - y
- f = (*Float).Sub
- case 2:
- op = "*"
- z = x * y
- f = (*Float).Mul
- case 3:
- op = "/"
- z = x / y
- f = (*Float).Quo
- default:
- panic("unreachable")
- }
- var errnan bool // set if execution of f panicked with ErrNaN
- // protect execution of f
- func() {
- defer func() {
- if p := recover(); p != nil {
- _ = p.(ErrNaN) // re-panic if not ErrNaN
- errnan = true
- }
- }()
- f(got, xx, yy)
- }()
- if math.IsNaN(z) {
- if !errnan {
- t.Errorf("%5g %s %5g = %5s; want ErrNaN panic", x, op, y, got)
- }
- continue
- }
- if errnan {
- t.Errorf("%5g %s %5g panicked with ErrNan; want %5s", x, op, y, want)
- continue
- }
- want.SetFloat64(z)
- if !alike(got, want) {
- t.Errorf("%5g %s %5g = %5s; want %5s", x, op, y, got, want)
- }
- }
- }
- }
-}
-
-func TestFloatArithmeticOverflow(t *testing.T) {
- for _, test := range []struct {
- prec uint
- mode RoundingMode
- op byte
- x, y, want string
- acc Accuracy
- }{
- {4, ToNearestEven, '+', "0", "0", "0", Exact}, // smoke test
- {4, ToNearestEven, '+', "0x.8p+0", "0x.8p+0", "0x.8p+1", Exact}, // smoke test
-
- {4, ToNearestEven, '+', "0", "0x.8p2147483647", "0x.8p+2147483647", Exact},
- {4, ToNearestEven, '+', "0x.8p2147483500", "0x.8p2147483647", "0x.8p+2147483647", Below}, // rounded to zero
- {4, ToNearestEven, '+', "0x.8p2147483647", "0x.8p2147483647", "+Inf", Above}, // exponent overflow in +
- {4, ToNearestEven, '+', "-0x.8p2147483647", "-0x.8p2147483647", "-Inf", Below}, // exponent overflow in +
- {4, ToNearestEven, '-', "-0x.8p2147483647", "0x.8p2147483647", "-Inf", Below}, // exponent overflow in -
-
- {4, ToZero, '+', "0x.fp2147483647", "0x.8p2147483643", "0x.fp+2147483647", Below}, // rounded to zero
- {4, ToNearestEven, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above}, // exponent overflow in rounding
- {4, AwayFromZero, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above}, // exponent overflow in rounding
-
- {4, AwayFromZero, '-', "-0x.fp2147483647", "0x.8p2147483644", "-Inf", Below}, // exponent overflow in rounding
- {4, ToNearestEven, '-', "-0x.fp2147483647", "0x.8p2147483643", "-Inf", Below}, // exponent overflow in rounding
- {4, ToZero, '-', "-0x.fp2147483647", "0x.8p2147483643", "-0x.fp+2147483647", Above}, // rounded to zero
-
- {4, ToNearestEven, '+', "0", "0x.8p-2147483648", "0x.8p-2147483648", Exact},
- {4, ToNearestEven, '+', "0x.8p-2147483648", "0x.8p-2147483648", "0x.8p-2147483647", Exact},
-
- {4, ToNearestEven, '*', "1", "0x.8p2147483647", "0x.8p+2147483647", Exact},
- {4, ToNearestEven, '*', "2", "0x.8p2147483647", "+Inf", Above}, // exponent overflow in *
- {4, ToNearestEven, '*', "-2", "0x.8p2147483647", "-Inf", Below}, // exponent overflow in *
-
- {4, ToNearestEven, '/', "0.5", "0x.8p2147483647", "0x.8p-2147483646", Exact},
- {4, ToNearestEven, '/', "0x.8p+0", "0x.8p2147483647", "0x.8p-2147483646", Exact},
- {4, ToNearestEven, '/', "0x.8p-1", "0x.8p2147483647", "0x.8p-2147483647", Exact},
- {4, ToNearestEven, '/', "0x.8p-2", "0x.8p2147483647", "0x.8p-2147483648", Exact},
- {4, ToNearestEven, '/', "0x.8p-3", "0x.8p2147483647", "0", Below}, // exponent underflow in /
- } {
- x := makeFloat(test.x)
- y := makeFloat(test.y)
- z := new(Float).SetPrec(test.prec).SetMode(test.mode)
- switch test.op {
- case '+':
- z.Add(x, y)
- case '-':
- z.Sub(x, y)
- case '*':
- z.Mul(x, y)
- case '/':
- z.Quo(x, y)
- default:
- panic("unreachable")
- }
- if got := z.Text('p', 0); got != test.want || z.Acc() != test.acc {
- t.Errorf(
- "prec = %d (%s): %s %c %s = %s (%s); want %s (%s)",
- test.prec, test.mode, x.Text('p', 0), test.op, y.Text('p', 0), got, z.Acc(), test.want, test.acc,
- )
- }
- }
-}
-
-// TODO(gri) Add tests that check correctness in the presence of aliasing.
-
-// For rounding modes ToNegativeInf and ToPositiveInf, rounding is affected
-// by the sign of the value to be rounded. Test that rounding happens after
-// the sign of a result has been set.
-// This test uses specific values that are known to fail if rounding is
-// "factored" out before setting the result sign.
-func TestFloatArithmeticRounding(t *testing.T) {
- for _, test := range []struct {
- mode RoundingMode
- prec uint
- x, y, want int64
- op byte
- }{
- {ToZero, 3, -0x8, -0x1, -0x8, '+'},
- {AwayFromZero, 3, -0x8, -0x1, -0xa, '+'},
- {ToNegativeInf, 3, -0x8, -0x1, -0xa, '+'},
-
- {ToZero, 3, -0x8, 0x1, -0x8, '-'},
- {AwayFromZero, 3, -0x8, 0x1, -0xa, '-'},
- {ToNegativeInf, 3, -0x8, 0x1, -0xa, '-'},
-
- {ToZero, 3, -0x9, 0x1, -0x8, '*'},
- {AwayFromZero, 3, -0x9, 0x1, -0xa, '*'},
- {ToNegativeInf, 3, -0x9, 0x1, -0xa, '*'},
-
- {ToZero, 3, -0x9, 0x1, -0x8, '/'},
- {AwayFromZero, 3, -0x9, 0x1, -0xa, '/'},
- {ToNegativeInf, 3, -0x9, 0x1, -0xa, '/'},
- } {
- var x, y, z Float
- x.SetInt64(test.x)
- y.SetInt64(test.y)
- z.SetPrec(test.prec).SetMode(test.mode)
- switch test.op {
- case '+':
- z.Add(&x, &y)
- case '-':
- z.Sub(&x, &y)
- case '*':
- z.Mul(&x, &y)
- case '/':
- z.Quo(&x, &y)
- default:
- panic("unreachable")
- }
- if got, acc := z.Int64(); got != test.want || acc != Exact {
- t.Errorf("%s, %d bits: %d %c %d = %d (%s); want %d (Exact)",
- test.mode, test.prec, test.x, test.op, test.y, got, acc, test.want,
- )
- }
- }
-}
-
-// TestFloatCmpSpecialValues tests that Cmp produces the correct results for
-// combinations of zero (±0), finite (±1 and ±2.71828), and infinite (±Inf)
-// operands.
-func TestFloatCmpSpecialValues(t *testing.T) {
- zero := 0.0
- args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)}
- xx := new(Float)
- yy := new(Float)
- for i := 0; i < 4; i++ {
- for _, x := range args {
- xx.SetFloat64(x)
- // check conversion is correct
- // (no need to do this for y, since we see exactly the
- // same values there)
- if got, acc := xx.Float64(); got != x || acc != Exact {
- t.Errorf("Float(%g) == %g (%s)", x, got, acc)
- }
- for _, y := range args {
- yy.SetFloat64(y)
- got := xx.Cmp(yy)
- want := 0
- switch {
- case x < y:
- want = -1
- case x > y:
- want = +1
- }
- if got != want {
- t.Errorf("(%g).Cmp(%g) = %v; want %v", x, y, got, want)
- }
- }
- }
- }
-}
diff --git a/src/cmd/compile/internal/big/floatconv.go b/src/cmd/compile/internal/big/floatconv.go
deleted file mode 100644
index a884df6..0000000
--- a/src/cmd/compile/internal/big/floatconv.go
+++ /dev/null
@@ -1,275 +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.
-
-// This file implements string-to-Float conversion functions.
-
-package big
-
-import (
- "fmt"
- "io"
- "strings"
-)
-
-// SetString sets z to the value of s and returns z and a boolean indicating
-// success. s must be a floating-point number of the same format as accepted
-// by Parse, with base argument 0.
-func (z *Float) SetString(s string) (*Float, bool) {
- if f, _, err := z.Parse(s, 0); err == nil {
- return f, true
- }
- return nil, false
-}
-
-// scan is like Parse but reads the longest possible prefix representing a valid
-// floating point number from an io.ByteScanner rather than a string. It serves
-// as the implementation of Parse. It does not recognize ±Inf and does not expect
-// EOF at the end.
-func (z *Float) scan(r io.ByteScanner, base int) (f *Float, b int, err error) {
- prec := z.prec
- if prec == 0 {
- prec = 64
- }
-
- // A reasonable value in case of an error.
- z.form = zero
-
- // sign
- z.neg, err = scanSign(r)
- if err != nil {
- return
- }
-
- // mantissa
- var fcount int // fractional digit count; valid if <= 0
- z.mant, b, fcount, err = z.mant.scan(r, base, true)
- if err != nil {
- return
- }
-
- // exponent
- var exp int64
- var ebase int
- exp, ebase, err = scanExponent(r, true)
- if err != nil {
- return
- }
-
- // special-case 0
- if len(z.mant) == 0 {
- z.prec = prec
- z.acc = Exact
- z.form = zero
- f = z
- return
- }
- // len(z.mant) > 0
-
- // The mantissa may have a decimal point (fcount <= 0) and there
- // may be a nonzero exponent exp. The decimal point amounts to a
- // division by b**(-fcount). An exponent means multiplication by
- // ebase**exp. Finally, mantissa normalization (shift left) requires
- // a correcting multiplication by 2**(-shiftcount). Multiplications
- // are commutative, so we can apply them in any order as long as there
- // is no loss of precision. We only have powers of 2 and 10, and
- // we split powers of 10 into the product of the same powers of
- // 2 and 5. This reduces the size of the multiplication factor
- // needed for base-10 exponents.
-
- // normalize mantissa and determine initial exponent contributions
- exp2 := int64(len(z.mant))*_W - fnorm(z.mant)
- exp5 := int64(0)
-
- // determine binary or decimal exponent contribution of decimal point
- if fcount < 0 {
- // The mantissa has a "decimal" point ddd.dddd; and
- // -fcount is the number of digits to the right of '.'.
- // Adjust relevant exponent accordingly.
- d := int64(fcount)
- switch b {
- case 10:
- exp5 = d
- fallthrough // 10**e == 5**e * 2**e
- case 2:
- exp2 += d
- case 16:
- exp2 += d * 4 // hexadecimal digits are 4 bits each
- default:
- panic("unexpected mantissa base")
- }
- // fcount consumed - not needed anymore
- }
-
- // take actual exponent into account
- switch ebase {
- case 10:
- exp5 += exp
- fallthrough
- case 2:
- exp2 += exp
- default:
- panic("unexpected exponent base")
- }
- // exp consumed - not needed anymore
-
- // apply 2**exp2
- if MinExp <= exp2 && exp2 <= MaxExp {
- z.prec = prec
- z.form = finite
- z.exp = int32(exp2)
- f = z
- } else {
- err = fmt.Errorf("exponent overflow")
- return
- }
-
- if exp5 == 0 {
- // no decimal exponent contribution
- z.round(0)
- return
- }
- // exp5 != 0
-
- // apply 5**exp5
- p := new(Float).SetPrec(z.Prec() + 64) // use more bits for p -- TODO(gri) what is the right number?
- if exp5 < 0 {
- z.Quo(z, p.pow5(uint64(-exp5)))
- } else {
- z.Mul(z, p.pow5(uint64(exp5)))
- }
-
- return
-}
-
-// These powers of 5 fit into a uint64.
-//
-// for p, q := uint64(0), uint64(1); p < q; p, q = q, q*5 {
-// fmt.Println(q)
-// }
-//
-var pow5tab = [...]uint64{
- 1,
- 5,
- 25,
- 125,
- 625,
- 3125,
- 15625,
- 78125,
- 390625,
- 1953125,
- 9765625,
- 48828125,
- 244140625,
- 1220703125,
- 6103515625,
- 30517578125,
- 152587890625,
- 762939453125,
- 3814697265625,
- 19073486328125,
- 95367431640625,
- 476837158203125,
- 2384185791015625,
- 11920928955078125,
- 59604644775390625,
- 298023223876953125,
- 1490116119384765625,
- 7450580596923828125,
-}
-
-// pow5 sets z to 5**n and returns z.
-// n must not be negative.
-func (z *Float) pow5(n uint64) *Float {
- const m = uint64(len(pow5tab) - 1)
- if n <= m {
- return z.SetUint64(pow5tab[n])
- }
- // n > m
-
- z.SetUint64(pow5tab[m])
- n -= m
-
- // use more bits for f than for z
- // TODO(gri) what is the right number?
- f := new(Float).SetPrec(z.Prec() + 64).SetUint64(5)
-
- for n > 0 {
- if n&1 != 0 {
- z.Mul(z, f)
- }
- f.Mul(f, f)
- n >>= 1
- }
-
- return z
-}
-
-// Parse parses s which must contain a text representation of a floating-
-// point number with a mantissa in the given conversion base (the exponent
-// is always a decimal number), or a string representing an infinite value.
-//
-// It sets z to the (possibly rounded) value of the corresponding floating-
-// point value, and returns z, the actual base b, and an error err, if any.
-// If z's precision is 0, it is changed to 64 before rounding takes effect.
-// The number must be of the form:
-//
-// number = [ sign ] [ prefix ] mantissa [ exponent ] | infinity .
-// sign = "+" | "-" .
-// prefix = "0" ( "x" | "X" | "b" | "B" ) .
-// mantissa = digits | digits "." [ digits ] | "." digits .
-// exponent = ( "E" | "e" | "p" ) [ sign ] digits .
-// digits = digit { digit } .
-// digit = "0" ... "9" | "a" ... "z" | "A" ... "Z" .
-// infinity = [ sign ] ( "inf" | "Inf" ) .
-//
-// The base argument must be 0, 2, 10, or 16. Providing an invalid base
-// argument will lead to a run-time panic.
-//
-// For base 0, the number prefix determines the actual base: A prefix of
-// "0x" or "0X" selects base 16, and a "0b" or "0B" prefix selects
-// base 2; otherwise, the actual base is 10 and no prefix is accepted.
-// The octal prefix "0" is not supported (a leading "0" is simply
-// considered a "0").
-//
-// A "p" exponent indicates a binary (rather then decimal) exponent;
-// for instance "0x1.fffffffffffffp1023" (using base 0) represents the
-// maximum float64 value. For hexadecimal mantissae, the exponent must
-// be binary, if present (an "e" or "E" exponent indicator cannot be
-// distinguished from a mantissa digit).
-//
-// The returned *Float f is nil and the value of z is valid but not
-// defined if an error is reported.
-//
-func (z *Float) Parse(s string, base int) (f *Float, b int, err error) {
- // scan doesn't handle ±Inf
- if len(s) == 3 && (s == "Inf" || s == "inf") {
- f = z.SetInf(false)
- return
- }
- if len(s) == 4 && (s[0] == '+' || s[0] == '-') && (s[1:] == "Inf" || s[1:] == "inf") {
- f = z.SetInf(s[0] == '-')
- return
- }
-
- r := strings.NewReader(s)
- if f, b, err = z.scan(r, base); err != nil {
- return
- }
-
- // entire string must have been consumed
- if ch, err2 := r.ReadByte(); err2 == nil {
- err = fmt.Errorf("expected end of string, found %q", ch)
- } else if err2 != io.EOF {
- err = err2
- }
-
- return
-}
-
-// ParseFloat is like f.Parse(s, base) with f set to the given precision
-// and rounding mode.
-func ParseFloat(s string, base int, prec uint, mode RoundingMode) (f *Float, b int, err error) {
- return new(Float).SetPrec(prec).SetMode(mode).Parse(s, base)
-}
diff --git a/src/cmd/compile/internal/big/floatconv_test.go b/src/cmd/compile/internal/big/floatconv_test.go
deleted file mode 100644
index b2a1ab0..0000000
--- a/src/cmd/compile/internal/big/floatconv_test.go
+++ /dev/null
@@ -1,667 +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.
-
-package big
-
-import (
- "fmt"
- "math"
- "strconv"
- "testing"
-)
-
-func TestFloatSetFloat64String(t *testing.T) {
- inf := math.Inf(0)
- nan := math.NaN()
-
- for _, test := range []struct {
- s string
- x float64 // NaNs represent invalid inputs
- }{
- // basics
- {"0", 0},
- {"-0", -0},
- {"+0", 0},
- {"1", 1},
- {"-1", -1},
- {"+1", 1},
- {"1.234", 1.234},
- {"-1.234", -1.234},
- {"+1.234", 1.234},
- {".1", 0.1},
- {"1.", 1},
- {"+1.", 1},
-
- // various zeros
- {"0e100", 0},
- {"-0e+100", 0},
- {"+0e-100", 0},
- {"0E100", 0},
- {"-0E+100", 0},
- {"+0E-100", 0},
-
- // various decimal exponent formats
- {"1.e10", 1e10},
- {"1e+10", 1e10},
- {"+1e-10", 1e-10},
- {"1E10", 1e10},
- {"1.E+10", 1e10},
- {"+1E-10", 1e-10},
-
- // infinities
- {"Inf", inf},
- {"+Inf", inf},
- {"-Inf", -inf},
- {"inf", inf},
- {"+inf", inf},
- {"-inf", -inf},
-
- // invalid numbers
- {"", nan},
- {"-", nan},
- {"0x", nan},
- {"0e", nan},
- {"1.2ef", nan},
- {"2..3", nan},
- {"123..", nan},
- {"infinity", nan},
- {"foobar", nan},
-
- // misc decimal values
- {"3.14159265", 3.14159265},
- {"-687436.79457e-245", -687436.79457e-245},
- {"-687436.79457E245", -687436.79457e245},
- {".0000000000000000000000000000000000000001", 1e-40},
- {"+10000000000000000000000000000000000000000e-0", 1e40},
-
- // decimal mantissa, binary exponent
- {"0p0", 0},
- {"-0p0", -0},
- {"1p10", 1 << 10},
- {"1p+10", 1 << 10},
- {"+1p-10", 1.0 / (1 << 10)},
- {"1024p-12", 0.25},
- {"-1p10", -1024},
- {"1.5p1", 3},
-
- // binary mantissa, decimal exponent
- {"0b0", 0},
- {"-0b0", -0},
- {"0b0e+10", 0},
- {"-0b0e-10", -0},
- {"0b1010", 10},
- {"0B1010E2", 1000},
- {"0b.1", 0.5},
- {"0b.001", 0.125},
- {"0b.001e3", 125},
-
- // binary mantissa, binary exponent
- {"0b0p+10", 0},
- {"-0b0p-10", -0},
- {"0b.1010p4", 10},
- {"0b1p-1", 0.5},
- {"0b001p-3", 0.125},
- {"0b.001p3", 1},
- {"0b0.01p2", 1},
-
- // hexadecimal mantissa and exponent
- {"0x0", 0},
- {"-0x0", -0},
- {"0x0p+10", 0},
- {"-0x0p-10", -0},
- {"0xff", 255},
- {"0X.8p1", 1},
- {"-0X0.00008p16", -0.5},
- {"0x0.0000000000001p-1022", math.SmallestNonzeroFloat64},
- {"0x1.fffffffffffffp1023", math.MaxFloat64},
- } {
- var x Float
- x.SetPrec(53)
- _, ok := x.SetString(test.s)
- if math.IsNaN(test.x) {
- // test.s is invalid
- if ok {
- t.Errorf("%s: want parse error", test.s)
- }
- continue
- }
- // test.s is valid
- if !ok {
- t.Errorf("%s: got parse error", test.s)
- continue
- }
- f, _ := x.Float64()
- want := new(Float).SetFloat64(test.x)
- if x.Cmp(want) != 0 {
- t.Errorf("%s: got %s (%v); want %v", test.s, &x, f, test.x)
- }
- }
-}
-
-func fdiv(a, b float64) float64 { return a / b }
-
-const (
- below1e23 = 99999999999999974834176
- above1e23 = 100000000000000008388608
-)
-
-func TestFloat64Text(t *testing.T) {
- for _, test := range []struct {
- x float64
- format byte
- prec int
- want string
- }{
- {0, 'f', 0, "0"},
- {math.Copysign(0, -1), 'f', 0, "-0"},
- {1, 'f', 0, "1"},
- {-1, 'f', 0, "-1"},
-
- {0.001, 'e', 0, "1e-03"},
- {0.459, 'e', 0, "5e-01"},
- {1.459, 'e', 0, "1e+00"},
- {2.459, 'e', 1, "2.5e+00"},
- {3.459, 'e', 2, "3.46e+00"},
- {4.459, 'e', 3, "4.459e+00"},
- {5.459, 'e', 4, "5.4590e+00"},
-
- {0.001, 'f', 0, "0"},
- {0.459, 'f', 0, "0"},
- {1.459, 'f', 0, "1"},
- {2.459, 'f', 1, "2.5"},
- {3.459, 'f', 2, "3.46"},
- {4.459, 'f', 3, "4.459"},
- {5.459, 'f', 4, "5.4590"},
-
- {0, 'b', 0, "0"},
- {math.Copysign(0, -1), 'b', 0, "-0"},
- {1.0, 'b', 0, "4503599627370496p-52"},
- {-1.0, 'b', 0, "-4503599627370496p-52"},
- {4503599627370496, 'b', 0, "4503599627370496p+0"},
-
- {0, 'p', 0, "0"},
- {math.Copysign(0, -1), 'p', 0, "-0"},
- {1024.0, 'p', 0, "0x.8p+11"},
- {-1024.0, 'p', 0, "-0x.8p+11"},
-
- // all test cases below from strconv/ftoa_test.go
- {1, 'e', 5, "1.00000e+00"},
- {1, 'f', 5, "1.00000"},
- {1, 'g', 5, "1"},
- {1, 'g', -1, "1"},
- {20, 'g', -1, "20"},
- {1234567.8, 'g', -1, "1.2345678e+06"},
- {200000, 'g', -1, "200000"},
- {2000000, 'g', -1, "2e+06"},
-
- // g conversion and zero suppression
- {400, 'g', 2, "4e+02"},
- {40, 'g', 2, "40"},
- {4, 'g', 2, "4"},
- {.4, 'g', 2, "0.4"},
- {.04, 'g', 2, "0.04"},
- {.004, 'g', 2, "0.004"},
- {.0004, 'g', 2, "0.0004"},
- {.00004, 'g', 2, "4e-05"},
- {.000004, 'g', 2, "4e-06"},
-
- {0, 'e', 5, "0.00000e+00"},
- {0, 'f', 5, "0.00000"},
- {0, 'g', 5, "0"},
- {0, 'g', -1, "0"},
-
- {-1, 'e', 5, "-1.00000e+00"},
- {-1, 'f', 5, "-1.00000"},
- {-1, 'g', 5, "-1"},
- {-1, 'g', -1, "-1"},
-
- {12, 'e', 5, "1.20000e+01"},
- {12, 'f', 5, "12.00000"},
- {12, 'g', 5, "12"},
- {12, 'g', -1, "12"},
-
- {123456700, 'e', 5, "1.23457e+08"},
- {123456700, 'f', 5, "123456700.00000"},
- {123456700, 'g', 5, "1.2346e+08"},
- {123456700, 'g', -1, "1.234567e+08"},
-
- {1.2345e6, 'e', 5, "1.23450e+06"},
- {1.2345e6, 'f', 5, "1234500.00000"},
- {1.2345e6, 'g', 5, "1.2345e+06"},
-
- {1e23, 'e', 17, "9.99999999999999916e+22"},
- {1e23, 'f', 17, "99999999999999991611392.00000000000000000"},
- {1e23, 'g', 17, "9.9999999999999992e+22"},
-
- {1e23, 'e', -1, "1e+23"},
- {1e23, 'f', -1, "100000000000000000000000"},
- {1e23, 'g', -1, "1e+23"},
-
- {below1e23, 'e', 17, "9.99999999999999748e+22"},
- {below1e23, 'f', 17, "99999999999999974834176.00000000000000000"},
- {below1e23, 'g', 17, "9.9999999999999975e+22"},
-
- {below1e23, 'e', -1, "9.999999999999997e+22"},
- {below1e23, 'f', -1, "99999999999999970000000"},
- {below1e23, 'g', -1, "9.999999999999997e+22"},
-
- {above1e23, 'e', 17, "1.00000000000000008e+23"},
- {above1e23, 'f', 17, "100000000000000008388608.00000000000000000"},
- {above1e23, 'g', 17, "1.0000000000000001e+23"},
-
- {above1e23, 'e', -1, "1.0000000000000001e+23"},
- {above1e23, 'f', -1, "100000000000000010000000"},
- {above1e23, 'g', -1, "1.0000000000000001e+23"},
-
- {5e-304 / 1e20, 'g', -1, "5e-324"},
- {-5e-304 / 1e20, 'g', -1, "-5e-324"},
- {fdiv(5e-304, 1e20), 'g', -1, "5e-324"}, // avoid constant arithmetic
- {fdiv(-5e-304, 1e20), 'g', -1, "-5e-324"}, // avoid constant arithmetic
-
- {32, 'g', -1, "32"},
- {32, 'g', 0, "3e+01"},
-
- {100, 'x', -1, "%x"},
-
- // {math.NaN(), 'g', -1, "NaN"}, // Float doesn't support NaNs
- // {-math.NaN(), 'g', -1, "NaN"}, // Float doesn't support NaNs
- {math.Inf(0), 'g', -1, "+Inf"},
- {math.Inf(-1), 'g', -1, "-Inf"},
- {-math.Inf(0), 'g', -1, "-Inf"},
-
- {-1, 'b', -1, "-4503599627370496p-52"},
-
- // fixed bugs
- {0.9, 'f', 1, "0.9"},
- {0.09, 'f', 1, "0.1"},
- {0.0999, 'f', 1, "0.1"},
- {0.05, 'f', 1, "0.1"},
- {0.05, 'f', 0, "0"},
- {0.5, 'f', 1, "0.5"},
- {0.5, 'f', 0, "0"},
- {1.5, 'f', 0, "2"},
-
- // http://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/
- {2.2250738585072011e-308, 'g', -1, "2.225073858507201e-308"},
-
- // Issue 2625.
- {383260575764816448, 'f', 0, "383260575764816448"},
- {383260575764816448, 'g', -1, "3.8326057576481645e+17"},
-
- // Issue 15918.
- {1, 'f', -10, "1"},
- {1, 'f', -11, "1"},
- {1, 'f', -12, "1"},
- } {
- // The test cases are from the strconv package which tests float64 values.
- // When formatting values with prec = -1 (shortest representation),
- // the actually available mantissa precision matters.
- // For denormalized values, that precision is < 53 (SetFloat64 default).
- // Compute and set the actual precision explicitly.
- f := new(Float).SetPrec(actualPrec(test.x)).SetFloat64(test.x)
- got := f.Text(test.format, test.prec)
- if got != test.want {
- t.Errorf("%v: got %s; want %s", test, got, test.want)
- continue
- }
-
- if test.format == 'b' && test.x == 0 {
- continue // 'b' format in strconv.Float requires knowledge of bias for 0.0
- }
- if test.format == 'p' {
- continue // 'p' format not supported in strconv.Format
- }
-
- // verify that Float format matches strconv format
- want := strconv.FormatFloat(test.x, test.format, test.prec, 64)
- if got != want {
- t.Errorf("%v: got %s; want %s (strconv)", test, got, want)
- }
- }
-}
-
-// actualPrec returns the number of actually used mantissa bits.
-func actualPrec(x float64) uint {
- if bits := math.Float64bits(x); x != 0 && bits&(0x7ff<<52) == 0 {
- // x is denormalized
- return 64 - nlz64(bits&(1<<52-1))
- }
- return 53
-}
-
-func TestFloatText(t *testing.T) {
- for _, test := range []struct {
- x string
- prec uint
- format byte
- digits int
- want string
- }{
- {"0", 10, 'f', 0, "0"},
- {"-0", 10, 'f', 0, "-0"},
- {"1", 10, 'f', 0, "1"},
- {"-1", 10, 'f', 0, "-1"},
-
- {"1.459", 100, 'e', 0, "1e+00"},
- {"2.459", 100, 'e', 1, "2.5e+00"},
- {"3.459", 100, 'e', 2, "3.46e+00"},
- {"4.459", 100, 'e', 3, "4.459e+00"},
- {"5.459", 100, 'e', 4, "5.4590e+00"},
-
- {"1.459", 100, 'E', 0, "1E+00"},
- {"2.459", 100, 'E', 1, "2.5E+00"},
- {"3.459", 100, 'E', 2, "3.46E+00"},
- {"4.459", 100, 'E', 3, "4.459E+00"},
- {"5.459", 100, 'E', 4, "5.4590E+00"},
-
- {"1.459", 100, 'f', 0, "1"},
- {"2.459", 100, 'f', 1, "2.5"},
- {"3.459", 100, 'f', 2, "3.46"},
- {"4.459", 100, 'f', 3, "4.459"},
- {"5.459", 100, 'f', 4, "5.4590"},
-
- {"1.459", 100, 'g', 0, "1"},
- {"2.459", 100, 'g', 1, "2"},
- {"3.459", 100, 'g', 2, "3.5"},
- {"4.459", 100, 'g', 3, "4.46"},
- {"5.459", 100, 'g', 4, "5.459"},
-
- {"1459", 53, 'g', 0, "1e+03"},
- {"2459", 53, 'g', 1, "2e+03"},
- {"3459", 53, 'g', 2, "3.5e+03"},
- {"4459", 53, 'g', 3, "4.46e+03"},
- {"5459", 53, 'g', 4, "5459"},
-
- {"1459", 53, 'G', 0, "1E+03"},
- {"2459", 53, 'G', 1, "2E+03"},
- {"3459", 53, 'G', 2, "3.5E+03"},
- {"4459", 53, 'G', 3, "4.46E+03"},
- {"5459", 53, 'G', 4, "5459"},
-
- {"3", 10, 'e', 40, "3.0000000000000000000000000000000000000000e+00"},
- {"3", 10, 'f', 40, "3.0000000000000000000000000000000000000000"},
- {"3", 10, 'g', 40, "3"},
-
- {"3e40", 100, 'e', 40, "3.0000000000000000000000000000000000000000e+40"},
- {"3e40", 100, 'f', 4, "30000000000000000000000000000000000000000.0000"},
- {"3e40", 100, 'g', 40, "3e+40"},
-
- // make sure "stupid" exponents don't stall the machine
- {"1e1000000", 64, 'p', 0, "0x.88b3a28a05eade3ap+3321929"},
- {"1e646456992", 64, 'p', 0, "0x.e883a0c5c8c7c42ap+2147483644"},
- {"1e646456993", 64, 'p', 0, "+Inf"},
- {"1e1000000000", 64, 'p', 0, "+Inf"},
- {"1e-1000000", 64, 'p', 0, "0x.efb4542cc8ca418ap-3321928"},
- {"1e-646456993", 64, 'p', 0, "0x.e17c8956983d9d59p-2147483647"},
- {"1e-646456994", 64, 'p', 0, "0"},
- {"1e-1000000000", 64, 'p', 0, "0"},
-
- // minimum and maximum values
- {"1p2147483646", 64, 'p', 0, "0x.8p+2147483647"},
- {"0x.8p2147483647", 64, 'p', 0, "0x.8p+2147483647"},
- {"0x.8p-2147483647", 64, 'p', 0, "0x.8p-2147483647"},
- {"1p-2147483649", 64, 'p', 0, "0x.8p-2147483648"},
-
- // TODO(gri) need tests for actual large Floats
-
- {"0", 53, 'b', 0, "0"},
- {"-0", 53, 'b', 0, "-0"},
- {"1.0", 53, 'b', 0, "4503599627370496p-52"},
- {"-1.0", 53, 'b', 0, "-4503599627370496p-52"},
- {"4503599627370496", 53, 'b', 0, "4503599627370496p+0"},
-
- // issue 9939
- {"3", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},
- {"03", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},
- {"3.", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},
- {"3.0", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},
- {"3.00", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},
- {"3.000", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"},
-
- {"3", 350, 'p', 0, "0x.cp+2"},
- {"03", 350, 'p', 0, "0x.cp+2"},
- {"3.", 350, 'p', 0, "0x.cp+2"},
- {"3.0", 350, 'p', 0, "0x.cp+2"},
- {"3.00", 350, 'p', 0, "0x.cp+2"},
- {"3.000", 350, 'p', 0, "0x.cp+2"},
-
- {"0", 64, 'p', 0, "0"},
- {"-0", 64, 'p', 0, "-0"},
- {"1024.0", 64, 'p', 0, "0x.8p+11"},
- {"-1024.0", 64, 'p', 0, "-0x.8p+11"},
-
- // unsupported format
- {"3.14", 64, 'x', 0, "%x"},
- {"-3.14", 64, 'x', 0, "%x"},
- } {
- f, _, err := ParseFloat(test.x, 0, test.prec, ToNearestEven)
- if err != nil {
- t.Errorf("%v: %s", test, err)
- continue
- }
-
- got := f.Text(test.format, test.digits)
- if got != test.want {
- t.Errorf("%v: got %s; want %s", test, got, test.want)
- }
-
- // compare with strconv.FormatFloat output if possible
- // ('p' format is not supported by strconv.FormatFloat,
- // and its output for 0.0 prints a biased exponent value
- // as in 0p-1074 which makes no sense to emulate here)
- if test.prec == 53 && test.format != 'p' && f.Sign() != 0 {
- f64, acc := f.Float64()
- if acc != Exact {
- t.Errorf("%v: expected exact conversion to float64", test)
- continue
- }
- got := strconv.FormatFloat(f64, test.format, test.digits, 64)
- if got != test.want {
- t.Errorf("%v: got %s; want %s", test, got, test.want)
- }
- }
- }
-}
-
-func TestFloatFormat(t *testing.T) {
- for _, test := range []struct {
- format string
- value interface{} // float32, float64, or string (== 512bit *Float)
- want string
- }{
- // from fmt/fmt_test.go
- {"%+.3e", 0.0, "+0.000e+00"},
- {"%+.3e", 1.0, "+1.000e+00"},
- {"%+.3f", -1.0, "-1.000"},
- {"%+.3F", -1.0, "-1.000"},
- {"%+.3F", float32(-1.0), "-1.000"},
- {"%+07.2f", 1.0, "+001.00"},
- {"%+07.2f", -1.0, "-001.00"},
- {"%+10.2f", +1.0, " +1.00"},
- {"%+10.2f", -1.0, " -1.00"},
- {"% .3E", -1.0, "-1.000E+00"},
- {"% .3e", 1.0, " 1.000e+00"},
- {"%+.3g", 0.0, "+0"},
- {"%+.3g", 1.0, "+1"},
- {"%+.3g", -1.0, "-1"},
- {"% .3g", -1.0, "-1"},
- {"% .3g", 1.0, " 1"},
- {"%b", float32(1.0), "8388608p-23"},
- {"%b", 1.0, "4503599627370496p-52"},
-
- // from fmt/fmt_test.go: old test/fmt_test.go
- {"%e", 1.0, "1.000000e+00"},
- {"%e", 1234.5678e3, "1.234568e+06"},
- {"%e", 1234.5678e-8, "1.234568e-05"},
- {"%e", -7.0, "-7.000000e+00"},
- {"%e", -1e-9, "-1.000000e-09"},
- {"%f", 1234.5678e3, "1234567.800000"},
- {"%f", 1234.5678e-8, "0.000012"},
- {"%f", -7.0, "-7.000000"},
- {"%f", -1e-9, "-0.000000"},
- {"%g", 1234.5678e3, "1.2345678e+06"},
- {"%g", float32(1234.5678e3), "1.2345678e+06"},
- {"%g", 1234.5678e-8, "1.2345678e-05"},
- {"%g", -7.0, "-7"},
- {"%g", -1e-9, "-1e-09"},
- {"%g", float32(-1e-9), "-1e-09"},
- {"%E", 1.0, "1.000000E+00"},
- {"%E", 1234.5678e3, "1.234568E+06"},
- {"%E", 1234.5678e-8, "1.234568E-05"},
- {"%E", -7.0, "-7.000000E+00"},
- {"%E", -1e-9, "-1.000000E-09"},
- {"%G", 1234.5678e3, "1.2345678E+06"},
- {"%G", float32(1234.5678e3), "1.2345678E+06"},
- {"%G", 1234.5678e-8, "1.2345678E-05"},
- {"%G", -7.0, "-7"},
- {"%G", -1e-9, "-1E-09"},
- {"%G", float32(-1e-9), "-1E-09"},
-
- {"%20.6e", 1.2345e3, " 1.234500e+03"},
- {"%20.6e", 1.2345e-3, " 1.234500e-03"},
- {"%20e", 1.2345e3, " 1.234500e+03"},
- {"%20e", 1.2345e-3, " 1.234500e-03"},
- {"%20.8e", 1.2345e3, " 1.23450000e+03"},
- {"%20f", 1.23456789e3, " 1234.567890"},
- {"%20f", 1.23456789e-3, " 0.001235"},
- {"%20f", 12345678901.23456789, " 12345678901.234568"},
- {"%-20f", 1.23456789e3, "1234.567890 "},
- {"%20.8f", 1.23456789e3, " 1234.56789000"},
- {"%20.8f", 1.23456789e-3, " 0.00123457"},
- {"%g", 1.23456789e3, "1234.56789"},
- {"%g", 1.23456789e-3, "0.00123456789"},
- {"%g", 1.23456789e20, "1.23456789e+20"},
- {"%20e", math.Inf(1), " +Inf"},
- {"%-20f", math.Inf(-1), "-Inf "},
-
- // from fmt/fmt_test.go: comparison of padding rules with C printf
- {"%.2f", 1.0, "1.00"},
- {"%.2f", -1.0, "-1.00"},
- {"% .2f", 1.0, " 1.00"},
- {"% .2f", -1.0, "-1.00"},
- {"%+.2f", 1.0, "+1.00"},
- {"%+.2f", -1.0, "-1.00"},
- {"%7.2f", 1.0, " 1.00"},
- {"%7.2f", -1.0, " -1.00"},
- {"% 7.2f", 1.0, " 1.00"},
- {"% 7.2f", -1.0, " -1.00"},
- {"%+7.2f", 1.0, " +1.00"},
- {"%+7.2f", -1.0, " -1.00"},
- {"%07.2f", 1.0, "0001.00"},
- {"%07.2f", -1.0, "-001.00"},
- {"% 07.2f", 1.0, " 001.00"},
- {"% 07.2f", -1.0, "-001.00"},
- {"%+07.2f", 1.0, "+001.00"},
- {"%+07.2f", -1.0, "-001.00"},
-
- // from fmt/fmt_test.go: zero padding does not apply to infinities
- {"%020f", math.Inf(-1), " -Inf"},
- {"%020f", math.Inf(+1), " +Inf"},
- {"% 020f", math.Inf(-1), " -Inf"},
- {"% 020f", math.Inf(+1), " Inf"},
- {"%+020f", math.Inf(-1), " -Inf"},
- {"%+020f", math.Inf(+1), " +Inf"},
- {"%20f", -1.0, " -1.000000"},
-
- // handle %v like %g
- {"%v", 0.0, "0"},
- {"%v", -7.0, "-7"},
- {"%v", -1e-9, "-1e-09"},
- {"%v", float32(-1e-9), "-1e-09"},
- {"%010v", 0.0, "0000000000"},
-
- // *Float cases
- {"%.20f", "1e-20", "0.00000000000000000001"},
- {"%.20f", "-1e-20", "-0.00000000000000000001"},
- {"%30.20f", "-1e-20", " -0.00000000000000000001"},
- {"%030.20f", "-1e-20", "-00000000.00000000000000000001"},
- {"%030.20f", "+1e-20", "000000000.00000000000000000001"},
- {"% 030.20f", "+1e-20", " 00000000.00000000000000000001"},
-
- // erroneous formats
- {"%s", 1.0, "%!s(*big.Float=1)"},
- } {
- value := new(Float)
- switch v := test.value.(type) {
- case float32:
- value.SetPrec(24).SetFloat64(float64(v))
- case float64:
- value.SetPrec(53).SetFloat64(v)
- case string:
- value.SetPrec(512).Parse(v, 0)
- default:
- t.Fatalf("unsupported test value: %v (%T)", v, v)
- }
-
- if got := fmt.Sprintf(test.format, value); got != test.want {
- t.Errorf("%v: got %q; want %q", test, got, test.want)
- }
- }
-}
-
-func BenchmarkParseFloatSmallExp(b *testing.B) {
- for i := 0; i < b.N; i++ {
- for _, s := range []string{
- "1e0",
- "1e-1",
- "1e-2",
- "1e-3",
- "1e-4",
- "1e-5",
- "1e-10",
- "1e-20",
- "1e-50",
- "1e1",
- "1e2",
- "1e3",
- "1e4",
- "1e5",
- "1e10",
- "1e20",
- "1e50",
- } {
- var x Float
- _, _, err := x.Parse(s, 0)
- if err != nil {
- b.Fatalf("%s: %v", s, err)
- }
- }
- }
-}
-
-func BenchmarkParseFloatLargeExp(b *testing.B) {
- for i := 0; i < b.N; i++ {
- for _, s := range []string{
- "1e0",
- "1e-10",
- "1e-20",
- "1e-30",
- "1e-40",
- "1e-50",
- "1e-100",
- "1e-500",
- "1e-1000",
- "1e-5000",
- "1e-10000",
- "1e10",
- "1e20",
- "1e30",
- "1e40",
- "1e50",
- "1e100",
- "1e500",
- "1e1000",
- "1e5000",
- "1e10000",
- } {
- var x Float
- _, _, err := x.Parse(s, 0)
- if err != nil {
- b.Fatalf("%s: %v", s, err)
- }
- }
- }
-}
diff --git a/src/cmd/compile/internal/big/floatexample_test.go b/src/cmd/compile/internal/big/floatexample_test.go
deleted file mode 100644
index beb9052..0000000
--- a/src/cmd/compile/internal/big/floatexample_test.go
+++ /dev/null
@@ -1,141 +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.
-
-package big_test
-
-import (
- "cmd/compile/internal/big"
- "fmt"
- "math"
-)
-
-func ExampleFloat_Add() {
- // Operate on numbers of different precision.
- var x, y, z big.Float
- x.SetInt64(1000) // x is automatically set to 64bit precision
- y.SetFloat64(2.718281828) // y is automatically set to 53bit precision
- z.SetPrec(32)
- z.Add(&x, &y)
- fmt.Printf("x = %.10g (%s, prec = %d, acc = %s)\n", &x, x.Text('p', 0), x.Prec(), x.Acc())
- fmt.Printf("y = %.10g (%s, prec = %d, acc = %s)\n", &y, y.Text('p', 0), y.Prec(), y.Acc())
- fmt.Printf("z = %.10g (%s, prec = %d, acc = %s)\n", &z, z.Text('p', 0), z.Prec(), z.Acc())
- // Output:
- // x = 1000 (0x.fap+10, prec = 64, acc = Exact)
- // y = 2.718281828 (0x.adf85458248cd8p+2, prec = 53, acc = Exact)
- // z = 1002.718282 (0x.faadf854p+10, prec = 32, acc = Below)
-}
-
-func ExampleFloat_shift() {
- // Implement Float "shift" by modifying the (binary) exponents directly.
- for s := -5; s <= 5; s++ {
- x := big.NewFloat(0.5)
- x.SetMantExp(x, x.MantExp(nil)+s) // shift x by s
- fmt.Println(x)
- }
- // Output:
- // 0.015625
- // 0.03125
- // 0.0625
- // 0.125
- // 0.25
- // 0.5
- // 1
- // 2
- // 4
- // 8
- // 16
-}
-
-func ExampleFloat_Cmp() {
- inf := math.Inf(1)
- zero := 0.0
-
- operands := []float64{-inf, -1.2, -zero, 0, +1.2, +inf}
-
- fmt.Println(" x y cmp")
- fmt.Println("---------------")
- for _, x64 := range operands {
- x := big.NewFloat(x64)
- for _, y64 := range operands {
- y := big.NewFloat(y64)
- fmt.Printf("%4g %4g %3d\n", x, y, x.Cmp(y))
- }
- fmt.Println()
- }
-
- // Output:
- // x y cmp
- // ---------------
- // -Inf -Inf 0
- // -Inf -1.2 -1
- // -Inf -0 -1
- // -Inf 0 -1
- // -Inf 1.2 -1
- // -Inf +Inf -1
- //
- // -1.2 -Inf 1
- // -1.2 -1.2 0
- // -1.2 -0 -1
- // -1.2 0 -1
- // -1.2 1.2 -1
- // -1.2 +Inf -1
- //
- // -0 -Inf 1
- // -0 -1.2 1
- // -0 -0 0
- // -0 0 0
- // -0 1.2 -1
- // -0 +Inf -1
- //
- // 0 -Inf 1
- // 0 -1.2 1
- // 0 -0 0
- // 0 0 0
- // 0 1.2 -1
- // 0 +Inf -1
- //
- // 1.2 -Inf 1
- // 1.2 -1.2 1
- // 1.2 -0 1
- // 1.2 0 1
- // 1.2 1.2 0
- // 1.2 +Inf -1
- //
- // +Inf -Inf 1
- // +Inf -1.2 1
- // +Inf -0 1
- // +Inf 0 1
- // +Inf 1.2 1
- // +Inf +Inf 0
-}
-
-func ExampleRoundingMode() {
- operands := []float64{2.6, 2.5, 2.1, -2.1, -2.5, -2.6}
-
- fmt.Print(" x")
- for mode := big.ToNearestEven; mode <= big.ToPositiveInf; mode++ {
- fmt.Printf(" %s", mode)
- }
- fmt.Println()
-
- for _, f64 := range operands {
- fmt.Printf("%4g", f64)
- for mode := big.ToNearestEven; mode <= big.ToPositiveInf; mode++ {
- // sample operands above require 2 bits to represent mantissa
- // set binary precision to 2 to round them to integer values
- f := new(big.Float).SetPrec(2).SetMode(mode).SetFloat64(f64)
- fmt.Printf(" %*g", len(mode.String()), f)
- }
- fmt.Println()
- }
-
- // Output:
- // x ToNearestEven ToNearestAway ToZero AwayFromZero ToNegativeInf ToPositiveInf
- // 2.6 3 3 2 3 2 3
- // 2.5 2 3 2 3 2 3
- // 2.1 2 2 2 3 2 3
- // -2.1 -2 -2 -2 -3 -3 -2
- // -2.5 -2 -3 -2 -3 -3 -2
- // -2.6 -3 -3 -2 -3 -3 -2
-}
diff --git a/src/cmd/compile/internal/big/floatmarsh.go b/src/cmd/compile/internal/big/floatmarsh.go
deleted file mode 100644
index 3725d4b..0000000
--- a/src/cmd/compile/internal/big/floatmarsh.go
+++ /dev/null
@@ -1,120 +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.
-
-// This file implements encoding/decoding of Floats.
-
-package big
-
-import (
- "encoding/binary"
- "fmt"
-)
-
-// Gob codec version. Permits backward-compatible changes to the encoding.
-const floatGobVersion byte = 1
-
-// GobEncode implements the gob.GobEncoder interface.
-// The Float value and all its attributes (precision,
-// rounding mode, accuracy) are marshalled.
-func (x *Float) GobEncode() ([]byte, error) {
- if x == nil {
- return nil, nil
- }
-
- // determine max. space (bytes) required for encoding
- sz := 1 + 1 + 4 // version + mode|acc|form|neg (3+2+2+1bit) + prec
- n := 0 // number of mantissa words
- if x.form == finite {
- // add space for mantissa and exponent
- n = int((x.prec + (_W - 1)) / _W) // required mantissa length in words for given precision
- // actual mantissa slice could be shorter (trailing 0's) or longer (unused bits):
- // - if shorter, only encode the words present
- // - if longer, cut off unused words when encoding in bytes
- // (in practice, this should never happen since rounding
- // takes care of it, but be safe and do it always)
- if len(x.mant) < n {
- n = len(x.mant)
- }
- // len(x.mant) >= n
- sz += 4 + n*_S // exp + mant
- }
- buf := make([]byte, sz)
-
- buf[0] = floatGobVersion
- b := byte(x.mode&7)<<5 | byte((x.acc+1)&3)<<3 | byte(x.form&3)<<1
- if x.neg {
- b |= 1
- }
- buf[1] = b
- binary.BigEndian.PutUint32(buf[2:], x.prec)
-
- if x.form == finite {
- binary.BigEndian.PutUint32(buf[6:], uint32(x.exp))
- x.mant[len(x.mant)-n:].bytes(buf[10:]) // cut off unused trailing words
- }
-
- return buf, nil
-}
-
-// GobDecode implements the gob.GobDecoder interface.
-// The result is rounded per the precision and rounding mode of
-// z unless z's precision is 0, in which case z is set exactly
-// to the decoded value.
-func (z *Float) GobDecode(buf []byte) error {
- if len(buf) == 0 {
- // Other side sent a nil or default value.
- *z = Float{}
- return nil
- }
-
- if buf[0] != floatGobVersion {
- return fmt.Errorf("Float.GobDecode: encoding version %d not supported", buf[0])
- }
-
- oldPrec := z.prec
- oldMode := z.mode
-
- b := buf[1]
- z.mode = RoundingMode((b >> 5) & 7)
- z.acc = Accuracy((b>>3)&3) - 1
- z.form = form((b >> 1) & 3)
- z.neg = b&1 != 0
- z.prec = binary.BigEndian.Uint32(buf[2:])
-
- if z.form == finite {
- z.exp = int32(binary.BigEndian.Uint32(buf[6:]))
- z.mant = z.mant.setBytes(buf[10:])
- }
-
- if oldPrec != 0 {
- z.mode = oldMode
- z.SetPrec(uint(oldPrec))
- }
-
- return nil
-}
-
-// MarshalText implements the encoding.TextMarshaler interface.
-// Only the Float value is marshaled (in full precision), other
-// attributes such as precision or accuracy are ignored.
-func (x *Float) MarshalText() (text []byte, err error) {
- if x == nil {
- return []byte("<nil>"), nil
- }
- var buf []byte
- return x.Append(buf, 'g', -1), nil
-}
-
-// UnmarshalText implements the encoding.TextUnmarshaler interface.
-// The result is rounded per the precision and rounding mode of z.
-// If z's precision is 0, it is changed to 64 before rounding takes
-// effect.
-func (z *Float) UnmarshalText(text []byte) error {
- // TODO(gri): get rid of the []byte/string conversion
- _, _, err := z.Parse(string(text), 0)
- if err != nil {
- err = fmt.Errorf("math/big: cannot unmarshal %q into a *big.Float (%v)", text, err)
- }
- return err
-}
diff --git a/src/cmd/compile/internal/big/floatmarsh_test.go b/src/cmd/compile/internal/big/floatmarsh_test.go
deleted file mode 100644
index 5bd906d..0000000
--- a/src/cmd/compile/internal/big/floatmarsh_test.go
+++ /dev/null
@@ -1,136 +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.
-
-package big
-
-import (
- "bytes"
- "encoding/gob"
- "encoding/json"
- "io"
- "testing"
-)
-
-var floatVals = []string{
- "0",
- "1",
- "0.1",
- "2.71828",
- "1234567890",
- "3.14e1234",
- "3.14e-1234",
- "0.738957395793475734757349579759957975985497e100",
- "0.73895739579347546656564656573475734957975995797598589749859834759476745986795497e100",
- "inf",
- "Inf",
-}
-
-func TestFloatGobEncoding(t *testing.T) {
- var medium bytes.Buffer
- enc := gob.NewEncoder(&medium)
- dec := gob.NewDecoder(&medium)
- for _, test := range floatVals {
- for _, sign := range []string{"", "+", "-"} {
- for _, prec := range []uint{0, 1, 2, 10, 53, 64, 100, 1000} {
- for _, mode := range []RoundingMode{ToNearestEven, ToNearestAway, ToZero, AwayFromZero, ToNegativeInf, ToPositiveInf} {
- medium.Reset() // empty buffer for each test case (in case of failures)
- x := sign + test
-
- var tx Float
- _, _, err := tx.SetPrec(prec).SetMode(mode).Parse(x, 0)
- if err != nil {
- t.Errorf("parsing of %s (%dbits, %v) failed (invalid test case): %v", x, prec, mode, err)
- continue
- }
-
- // If tx was set to prec == 0, tx.Parse(x, 0) assumes precision 64. Correct it.
- if prec == 0 {
- tx.SetPrec(0)
- }
-
- if err := enc.Encode(&tx); err != nil {
- t.Errorf("encoding of %v (%dbits, %v) failed: %v", &tx, prec, mode, err)
- continue
- }
-
- var rx Float
- if err := dec.Decode(&rx); err != nil {
- t.Errorf("decoding of %v (%dbits, %v) failed: %v", &tx, prec, mode, err)
- continue
- }
-
- if rx.Cmp(&tx) != 0 {
- t.Errorf("transmission of %s failed: got %s want %s", x, rx.String(), tx.String())
- continue
- }
-
- if rx.Prec() != prec {
- t.Errorf("transmission of %s's prec failed: got %d want %d", x, rx.Prec(), prec)
- }
-
- if rx.Mode() != mode {
- t.Errorf("transmission of %s's mode failed: got %s want %s", x, rx.Mode(), mode)
- }
-
- if rx.Acc() != tx.Acc() {
- t.Errorf("transmission of %s's accuracy failed: got %s want %s", x, rx.Acc(), tx.Acc())
- }
- }
- }
- }
- }
-}
-
-func TestFloatCorruptGob(t *testing.T) {
- var buf bytes.Buffer
- tx := NewFloat(4 / 3).SetPrec(1000).SetMode(ToPositiveInf)
- if err := gob.NewEncoder(&buf).Encode(tx); err != nil {
- t.Fatal(err)
- }
- b := buf.Bytes()
-
- var rx Float
- if err := gob.NewDecoder(bytes.NewReader(b)).Decode(&rx); err != nil {
- t.Fatal(err)
- }
-
- if err := gob.NewDecoder(bytes.NewReader(b[:10])).Decode(&rx); err != io.ErrUnexpectedEOF {
- t.Errorf("got %v want EOF", err)
- }
-
- b[1] = 0
- if err := gob.NewDecoder(bytes.NewReader(b)).Decode(&rx); err == nil {
- t.Fatal("got nil want version error")
- }
-}
-
-func TestFloatJSONEncoding(t *testing.T) {
- for _, test := range floatVals {
- for _, sign := range []string{"", "+", "-"} {
- for _, prec := range []uint{0, 1, 2, 10, 53, 64, 100, 1000} {
- x := sign + test
- var tx Float
- _, _, err := tx.SetPrec(prec).Parse(x, 0)
- if err != nil {
- t.Errorf("parsing of %s (prec = %d) failed (invalid test case): %v", x, prec, err)
- continue
- }
- b, err := json.Marshal(&tx)
- if err != nil {
- t.Errorf("marshaling of %v (prec = %d) failed: %v", &tx, prec, err)
- continue
- }
- var rx Float
- rx.SetPrec(prec)
- if err := json.Unmarshal(b, &rx); err != nil {
- t.Errorf("unmarshaling of %v (prec = %d) failed: %v", &tx, prec, err)
- continue
- }
- if rx.Cmp(&tx) != 0 {
- t.Errorf("JSON encoding of %v (prec = %d) failed: got %v want %v", &tx, prec, &rx, &tx)
- }
- }
- }
- }
-}
diff --git a/src/cmd/compile/internal/big/ftoa.go b/src/cmd/compile/internal/big/ftoa.go
deleted file mode 100644
index 57b16e1..0000000
--- a/src/cmd/compile/internal/big/ftoa.go
+++ /dev/null
@@ -1,459 +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.
-
-// This file implements Float-to-string conversion functions.
-// It is closely following the corresponding implementation
-// in strconv/ftoa.go, but modified and simplified for Float.
-
-package big
-
-import (
- "bytes"
- "fmt"
- "strconv"
-)
-
-// Text converts the floating-point number x to a string according
-// to the given format and precision prec. The format is one of:
-//
-// 'e' -d.dddde±dd, decimal exponent, at least two (possibly 0) exponent digits
-// 'E' -d.ddddE±dd, decimal exponent, at least two (possibly 0) exponent digits
-// 'f' -ddddd.dddd, no exponent
-// 'g' like 'e' for large exponents, like 'f' otherwise
-// 'G' like 'E' for large exponents, like 'f' otherwise
-// 'b' -ddddddp±dd, binary exponent
-// 'p' -0x.dddp±dd, binary exponent, hexadecimal mantissa
-//
-// For the binary exponent formats, the mantissa is printed in normalized form:
-//
-// 'b' decimal integer mantissa using x.Prec() bits, or -0
-// 'p' hexadecimal fraction with 0.5 <= 0.mantissa < 1.0, or -0
-//
-// If format is a different character, Text returns a "%" followed by the
-// unrecognized format character.
-//
-// The precision prec controls the number of digits (excluding the exponent)
-// printed by the 'e', 'E', 'f', 'g', and 'G' formats. For 'e', 'E', and 'f'
-// it is the number of digits after the decimal point. For 'g' and 'G' it is
-// the total number of digits. A negative precision selects the smallest
-// number of decimal digits necessary to identify the value x uniquely using
-// x.Prec() mantissa bits.
-// The prec value is ignored for the 'b' or 'p' format.
-func (x *Float) Text(format byte, prec int) string {
- cap := 10 // TODO(gri) determine a good/better value here
- if prec > 0 {
- cap += prec
- }
- return string(x.Append(make([]byte, 0, cap), format, prec))
-}
-
-// String formats x like x.Text('g', 10).
-// (String must be called explicitly, Float.Format does not support %s verb.)
-func (x *Float) String() string {
- return x.Text('g', 10)
-}
-
-// Append appends to buf the string form of the floating-point number x,
-// as generated by x.Text, and returns the extended buffer.
-func (x *Float) Append(buf []byte, fmt byte, prec int) []byte {
- // sign
- if x.neg {
- buf = append(buf, '-')
- }
-
- // Inf
- if x.form == inf {
- if !x.neg {
- buf = append(buf, '+')
- }
- return append(buf, "Inf"...)
- }
-
- // pick off easy formats
- switch fmt {
- case 'b':
- return x.fmtB(buf)
- case 'p':
- return x.fmtP(buf)
- }
-
- // Algorithm:
- // 1) convert Float to multiprecision decimal
- // 2) round to desired precision
- // 3) read digits out and format
-
- // 1) convert Float to multiprecision decimal
- var d decimal // == 0.0
- if x.form == finite {
- // x != 0
- d.init(x.mant, int(x.exp)-x.mant.bitLen())
- }
-
- // 2) round to desired precision
- shortest := false
- if prec < 0 {
- shortest = true
- roundShortest(&d, x)
- // Precision for shortest representation mode.
- switch fmt {
- case 'e', 'E':
- prec = len(d.mant) - 1
- case 'f':
- prec = max(len(d.mant)-d.exp, 0)
- case 'g', 'G':
- prec = len(d.mant)
- }
- } else {
- // round appropriately
- switch fmt {
- case 'e', 'E':
- // one digit before and number of digits after decimal point
- d.round(1 + prec)
- case 'f':
- // number of digits before and after decimal point
- d.round(d.exp + prec)
- case 'g', 'G':
- if prec == 0 {
- prec = 1
- }
- d.round(prec)
- }
- }
-
- // 3) read digits out and format
- switch fmt {
- case 'e', 'E':
- return fmtE(buf, fmt, prec, d)
- case 'f':
- return fmtF(buf, prec, d)
- case 'g', 'G':
- // trim trailing fractional zeros in %e format
- eprec := prec
- if eprec > len(d.mant) && len(d.mant) >= d.exp {
- eprec = len(d.mant)
- }
- // %e is used if the exponent from the conversion
- // is less than -4 or greater than or equal to the precision.
- // If precision was the shortest possible, use eprec = 6 for
- // this decision.
- if shortest {
- eprec = 6
- }
- exp := d.exp - 1
- if exp < -4 || exp >= eprec {
- if prec > len(d.mant) {
- prec = len(d.mant)
- }
- return fmtE(buf, fmt+'e'-'g', prec-1, d)
- }
- if prec > d.exp {
- prec = len(d.mant)
- }
- return fmtF(buf, max(prec-d.exp, 0), d)
- }
-
- // unknown format
- if x.neg {
- buf = buf[:len(buf)-1] // sign was added prematurely - remove it again
- }
- return append(buf, '%', fmt)
-}
-
-func roundShortest(d *decimal, x *Float) {
- // if the mantissa is zero, the number is zero - stop now
- if len(d.mant) == 0 {
- return
- }
-
- // Approach: All numbers in the interval [x - 1/2ulp, x + 1/2ulp]
- // (possibly exclusive) round to x for the given precision of x.
- // Compute the lower and upper bound in decimal form and find the
- // shortest decimal number d such that lower <= d <= upper.
-
- // TODO(gri) strconv/ftoa.do describes a shortcut in some cases.
- // See if we can use it (in adjusted form) here as well.
-
- // 1) Compute normalized mantissa mant and exponent exp for x such
- // that the lsb of mant corresponds to 1/2 ulp for the precision of
- // x (i.e., for mant we want x.prec + 1 bits).
- mant := nat(nil).set(x.mant)
- exp := int(x.exp) - mant.bitLen()
- s := mant.bitLen() - int(x.prec+1)
- switch {
- case s < 0:
- mant = mant.shl(mant, uint(-s))
- case s > 0:
- mant = mant.shr(mant, uint(+s))
- }
- exp += s
- // x = mant * 2**exp with lsb(mant) == 1/2 ulp of x.prec
-
- // 2) Compute lower bound by subtracting 1/2 ulp.
- var lower decimal
- var tmp nat
- lower.init(tmp.sub(mant, natOne), exp)
-
- // 3) Compute upper bound by adding 1/2 ulp.
- var upper decimal
- upper.init(tmp.add(mant, natOne), exp)
-
- // The upper and lower bounds are possible outputs only if
- // the original mantissa is even, so that ToNearestEven rounding
- // would round to the original mantissa and not the neighbors.
- inclusive := mant[0]&2 == 0 // test bit 1 since original mantissa was shifted by 1
-
- // Now we can figure out the minimum number of digits required.
- // Walk along until d has distinguished itself from upper and lower.
- for i, m := range d.mant {
- l := lower.at(i)
- u := upper.at(i)
-
- // Okay to round down (truncate) if lower has a different digit
- // or if lower is inclusive and is exactly the result of rounding
- // down (i.e., and we have reached the final digit of lower).
- okdown := l != m || inclusive && i+1 == len(lower.mant)
-
- // Okay to round up if upper has a different digit and either upper
- // is inclusive or upper is bigger than the result of rounding up.
- okup := m != u && (inclusive || m+1 < u || i+1 < len(upper.mant))
-
- // If it's okay to do either, then round to the nearest one.
- // If it's okay to do only one, do it.
- switch {
- case okdown && okup:
- d.round(i + 1)
- return
- case okdown:
- d.roundDown(i + 1)
- return
- case okup:
- d.roundUp(i + 1)
- return
- }
- }
-}
-
-// %e: d.ddddde±dd
-func fmtE(buf []byte, fmt byte, prec int, d decimal) []byte {
- // first digit
- ch := byte('0')
- if len(d.mant) > 0 {
- ch = d.mant[0]
- }
- buf = append(buf, ch)
-
- // .moredigits
- if prec > 0 {
- buf = append(buf, '.')
- i := 1
- m := min(len(d.mant), prec+1)
- if i < m {
- buf = append(buf, d.mant[i:m]...)
- i = m
- }
- for ; i <= prec; i++ {
- buf = append(buf, '0')
- }
- }
-
- // e±
- buf = append(buf, fmt)
- var exp int64
- if len(d.mant) > 0 {
- exp = int64(d.exp) - 1 // -1 because first digit was printed before '.'
- }
- if exp < 0 {
- ch = '-'
- exp = -exp
- } else {
- ch = '+'
- }
- buf = append(buf, ch)
-
- // dd...d
- if exp < 10 {
- buf = append(buf, '0') // at least 2 exponent digits
- }
- return strconv.AppendInt(buf, exp, 10)
-}
-
-// %f: ddddddd.ddddd
-func fmtF(buf []byte, prec int, d decimal) []byte {
- // integer, padded with zeros as needed
- if d.exp > 0 {
- m := min(len(d.mant), d.exp)
- buf = append(buf, d.mant[:m]...)
- for ; m < d.exp; m++ {
- buf = append(buf, '0')
- }
- } else {
- buf = append(buf, '0')
- }
-
- // fraction
- if prec > 0 {
- buf = append(buf, '.')
- for i := 0; i < prec; i++ {
- buf = append(buf, d.at(d.exp+i))
- }
- }
-
- return buf
-}
-
-// fmtB appends the string of x in the format mantissa "p" exponent
-// with a decimal mantissa and a binary exponent, or 0" if x is zero,
-// and returns the extended buffer.
-// The mantissa is normalized such that is uses x.Prec() bits in binary
-// representation.
-// The sign of x is ignored, and x must not be an Inf.
-func (x *Float) fmtB(buf []byte) []byte {
- if x.form == zero {
- return append(buf, '0')
- }
-
- if debugFloat && x.form != finite {
- panic("non-finite float")
- }
- // x != 0
-
- // adjust mantissa to use exactly x.prec bits
- m := x.mant
- switch w := uint32(len(x.mant)) * _W; {
- case w < x.prec:
- m = nat(nil).shl(m, uint(x.prec-w))
- case w > x.prec:
- m = nat(nil).shr(m, uint(w-x.prec))
- }
-
- buf = append(buf, m.utoa(10)...)
- buf = append(buf, 'p')
- e := int64(x.exp) - int64(x.prec)
- if e >= 0 {
- buf = append(buf, '+')
- }
- return strconv.AppendInt(buf, e, 10)
-}
-
-// fmtP appends the string of x in the format "0x." mantissa "p" exponent
-// with a hexadecimal mantissa and a binary exponent, or "0" if x is zero,
-// and returns the extended buffer.
-// The mantissa is normalized such that 0.5 <= 0.mantissa < 1.0.
-// The sign of x is ignored, and x must not be an Inf.
-func (x *Float) fmtP(buf []byte) []byte {
- if x.form == zero {
- return append(buf, '0')
- }
-
- if debugFloat && x.form != finite {
- panic("non-finite float")
- }
- // x != 0
-
- // remove trailing 0 words early
- // (no need to convert to hex 0's and trim later)
- m := x.mant
- i := 0
- for i < len(m) && m[i] == 0 {
- i++
- }
- m = m[i:]
-
- buf = append(buf, "0x."...)
- buf = append(buf, bytes.TrimRight(m.utoa(16), "0")...)
- buf = append(buf, 'p')
- if x.exp >= 0 {
- buf = append(buf, '+')
- }
- return strconv.AppendInt(buf, int64(x.exp), 10)
-}
-
-func min(x, y int) int {
- if x < y {
- return x
- }
- return y
-}
-
-// Format implements fmt.Formatter. It accepts all the regular
-// formats for floating-point numbers ('b', 'e', 'E', 'f', 'F',
-// 'g', 'G') as well as 'p' and 'v'. See (*Float).Text for the
-// interpretation of 'p'. The 'v' format is handled like 'g'.
-// Format also supports specification of the minimum precision
-// in digits, the output field width, as well as the format flags
-// '+' and ' ' for sign control, '0' for space or zero padding,
-// and '-' for left or right justification. See the fmt package
-// for details.
-func (x *Float) Format(s fmt.State, format rune) {
- prec, hasPrec := s.Precision()
- if !hasPrec {
- prec = 6 // default precision for 'e', 'f'
- }
-
- switch format {
- case 'e', 'E', 'f', 'b', 'p':
- // nothing to do
- case 'F':
- // (*Float).Text doesn't support 'F'; handle like 'f'
- format = 'f'
- case 'v':
- // handle like 'g'
- format = 'g'
- fallthrough
- case 'g', 'G':
- if !hasPrec {
- prec = -1 // default precision for 'g', 'G'
- }
- default:
- fmt.Fprintf(s, "%%!%c(*big.Float=%s)", format, x.String())
- return
- }
- var buf []byte
- buf = x.Append(buf, byte(format), prec)
- if len(buf) == 0 {
- buf = []byte("?") // should never happen, but don't crash
- }
- // len(buf) > 0
-
- var sign string
- switch {
- case buf[0] == '-':
- sign = "-"
- buf = buf[1:]
- case buf[0] == '+':
- // +Inf
- sign = "+"
- if s.Flag(' ') {
- sign = " "
- }
- buf = buf[1:]
- case s.Flag('+'):
- sign = "+"
- case s.Flag(' '):
- sign = " "
- }
-
- var padding int
- if width, hasWidth := s.Width(); hasWidth && width > len(sign)+len(buf) {
- padding = width - len(sign) - len(buf)
- }
-
- switch {
- case s.Flag('0') && !x.IsInf():
- // 0-padding on left
- writeMultiple(s, sign, 1)
- writeMultiple(s, "0", padding)
- s.Write(buf)
- case s.Flag('-'):
- // padding on right
- writeMultiple(s, sign, 1)
- s.Write(buf)
- writeMultiple(s, " ", padding)
- default:
- // padding on left
- writeMultiple(s, " ", padding)
- writeMultiple(s, sign, 1)
- s.Write(buf)
- }
-}
diff --git a/src/cmd/compile/internal/big/gcd_test.go b/src/cmd/compile/internal/big/gcd_test.go
deleted file mode 100644
index a929bf5..0000000
--- a/src/cmd/compile/internal/big/gcd_test.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2012 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.
-
-// This file implements a GCD benchmark.
-// Usage: go test math/big -test.bench GCD
-
-package big
-
-import (
- "math/rand"
- "testing"
-)
-
-// randInt returns a pseudo-random Int in the range [1<<(size-1), (1<<size) - 1]
-func randInt(r *rand.Rand, size uint) *Int {
- n := new(Int).Lsh(intOne, size-1)
- x := new(Int).Rand(r, n)
- return x.Add(x, n) // make sure result > 1<<(size-1)
-}
-
-func runGCD(b *testing.B, aSize, bSize uint) {
- b.Run("WithoutXY", func(b *testing.B) {
- runGCDExt(b, aSize, bSize, false)
- })
- b.Run("WithXY", func(b *testing.B) {
- runGCDExt(b, aSize, bSize, true)
- })
-}
-
-func runGCDExt(b *testing.B, aSize, bSize uint, calcXY bool) {
- b.StopTimer()
- var r = rand.New(rand.NewSource(1234))
- aa := randInt(r, aSize)
- bb := randInt(r, bSize)
- var x, y *Int
- if calcXY {
- x = new(Int)
- y = new(Int)
- }
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- new(Int).GCD(x, y, aa, bb)
- }
-}
-
-func BenchmarkGCD10x10(b *testing.B) { runGCD(b, 10, 10) }
-func BenchmarkGCD10x100(b *testing.B) { runGCD(b, 10, 100) }
-func BenchmarkGCD10x1000(b *testing.B) { runGCD(b, 10, 1000) }
-func BenchmarkGCD10x10000(b *testing.B) { runGCD(b, 10, 10000) }
-func BenchmarkGCD10x100000(b *testing.B) { runGCD(b, 10, 100000) }
-func BenchmarkGCD100x100(b *testing.B) { runGCD(b, 100, 100) }
-func BenchmarkGCD100x1000(b *testing.B) { runGCD(b, 100, 1000) }
-func BenchmarkGCD100x10000(b *testing.B) { runGCD(b, 100, 10000) }
-func BenchmarkGCD100x100000(b *testing.B) { runGCD(b, 100, 100000) }
-func BenchmarkGCD1000x1000(b *testing.B) { runGCD(b, 1000, 1000) }
-func BenchmarkGCD1000x10000(b *testing.B) { runGCD(b, 1000, 10000) }
-func BenchmarkGCD1000x100000(b *testing.B) { runGCD(b, 1000, 100000) }
-func BenchmarkGCD10000x10000(b *testing.B) { runGCD(b, 10000, 10000) }
-func BenchmarkGCD10000x100000(b *testing.B) { runGCD(b, 10000, 100000) }
-func BenchmarkGCD100000x100000(b *testing.B) { runGCD(b, 100000, 100000) }
diff --git a/src/cmd/compile/internal/big/hilbert_test.go b/src/cmd/compile/internal/big/hilbert_test.go
deleted file mode 100644
index 1a84341..0000000
--- a/src/cmd/compile/internal/big/hilbert_test.go
+++ /dev/null
@@ -1,160 +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.
-
-// A little test program and benchmark for rational arithmetics.
-// Computes a Hilbert matrix, its inverse, multiplies them
-// and verifies that the product is the identity matrix.
-
-package big
-
-import (
- "fmt"
- "testing"
-)
-
-type matrix struct {
- n, m int
- a []*Rat
-}
-
-func (a *matrix) at(i, j int) *Rat {
- if !(0 <= i && i < a.n && 0 <= j && j < a.m) {
- panic("index out of range")
- }
- return a.a[i*a.m+j]
-}
-
-func (a *matrix) set(i, j int, x *Rat) {
- if !(0 <= i && i < a.n && 0 <= j && j < a.m) {
- panic("index out of range")
- }
- a.a[i*a.m+j] = x
-}
-
-func newMatrix(n, m int) *matrix {
- if !(0 <= n && 0 <= m) {
- panic("illegal matrix")
- }
- a := new(matrix)
- a.n = n
- a.m = m
- a.a = make([]*Rat, n*m)
- return a
-}
-
-func newUnit(n int) *matrix {
- a := newMatrix(n, n)
- for i := 0; i < n; i++ {
- for j := 0; j < n; j++ {
- x := NewRat(0, 1)
- if i == j {
- x.SetInt64(1)
- }
- a.set(i, j, x)
- }
- }
- return a
-}
-
-func newHilbert(n int) *matrix {
- a := newMatrix(n, n)
- for i := 0; i < n; i++ {
- for j := 0; j < n; j++ {
- a.set(i, j, NewRat(1, int64(i+j+1)))
- }
- }
- return a
-}
-
-func newInverseHilbert(n int) *matrix {
- a := newMatrix(n, n)
- for i := 0; i < n; i++ {
- for j := 0; j < n; j++ {
- x1 := new(Rat).SetInt64(int64(i + j + 1))
- x2 := new(Rat).SetInt(new(Int).Binomial(int64(n+i), int64(n-j-1)))
- x3 := new(Rat).SetInt(new(Int).Binomial(int64(n+j), int64(n-i-1)))
- x4 := new(Rat).SetInt(new(Int).Binomial(int64(i+j), int64(i)))
-
- x1.Mul(x1, x2)
- x1.Mul(x1, x3)
- x1.Mul(x1, x4)
- x1.Mul(x1, x4)
-
- if (i+j)&1 != 0 {
- x1.Neg(x1)
- }
-
- a.set(i, j, x1)
- }
- }
- return a
-}
-
-func (a *matrix) mul(b *matrix) *matrix {
- if a.m != b.n {
- panic("illegal matrix multiply")
- }
- c := newMatrix(a.n, b.m)
- for i := 0; i < c.n; i++ {
- for j := 0; j < c.m; j++ {
- x := NewRat(0, 1)
- for k := 0; k < a.m; k++ {
- x.Add(x, new(Rat).Mul(a.at(i, k), b.at(k, j)))
- }
- c.set(i, j, x)
- }
- }
- return c
-}
-
-func (a *matrix) eql(b *matrix) bool {
- if a.n != b.n || a.m != b.m {
- return false
- }
- for i := 0; i < a.n; i++ {
- for j := 0; j < a.m; j++ {
- if a.at(i, j).Cmp(b.at(i, j)) != 0 {
- return false
- }
- }
- }
- return true
-}
-
-func (a *matrix) String() string {
- s := ""
- for i := 0; i < a.n; i++ {
- for j := 0; j < a.m; j++ {
- s += fmt.Sprintf("\t%s", a.at(i, j))
- }
- s += "\n"
- }
- return s
-}
-
-func doHilbert(t *testing.T, n int) {
- a := newHilbert(n)
- b := newInverseHilbert(n)
- I := newUnit(n)
- ab := a.mul(b)
- if !ab.eql(I) {
- if t == nil {
- panic("Hilbert failed")
- }
- t.Errorf("a = %s\n", a)
- t.Errorf("b = %s\n", b)
- t.Errorf("a*b = %s\n", ab)
- t.Errorf("I = %s\n", I)
- }
-}
-
-func TestHilbert(t *testing.T) {
- doHilbert(t, 10)
-}
-
-func BenchmarkHilbert(b *testing.B) {
- for i := 0; i < b.N; i++ {
- doHilbert(nil, 10)
- }
-}
diff --git a/src/cmd/compile/internal/big/int.go b/src/cmd/compile/internal/big/int.go
deleted file mode 100644
index f2a75d1..0000000
--- a/src/cmd/compile/internal/big/int.go
+++ /dev/null
@@ -1,934 +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.
-
-// This file implements signed multi-precision integers.
-
-package big
-
-import (
- "fmt"
- "io"
- "math/rand"
- "strings"
-)
-
-// An Int represents a signed multi-precision integer.
-// The zero value for an Int represents the value 0.
-type Int struct {
- neg bool // sign
- abs nat // absolute value of the integer
-}
-
-var intOne = &Int{false, natOne}
-
-// Sign returns:
-//
-// -1 if x < 0
-// 0 if x == 0
-// +1 if x > 0
-//
-func (x *Int) Sign() int {
- if len(x.abs) == 0 {
- return 0
- }
- if x.neg {
- return -1
- }
- return 1
-}
-
-// SetInt64 sets z to x and returns z.
-func (z *Int) SetInt64(x int64) *Int {
- neg := false
- if x < 0 {
- neg = true
- x = -x
- }
- z.abs = z.abs.setUint64(uint64(x))
- z.neg = neg
- return z
-}
-
-// SetUint64 sets z to x and returns z.
-func (z *Int) SetUint64(x uint64) *Int {
- z.abs = z.abs.setUint64(x)
- z.neg = false
- return z
-}
-
-// NewInt allocates and returns a new Int set to x.
-func NewInt(x int64) *Int {
- return new(Int).SetInt64(x)
-}
-
-// Set sets z to x and returns z.
-func (z *Int) Set(x *Int) *Int {
- if z != x {
- z.abs = z.abs.set(x.abs)
- z.neg = x.neg
- }
- return z
-}
-
-// Bits provides raw (unchecked but fast) access to x by returning its
-// absolute value as a little-endian Word slice. The result and x share
-// the same underlying array.
-// Bits is intended to support implementation of missing low-level Int
-// functionality outside this package; it should be avoided otherwise.
-func (x *Int) Bits() []Word {
- return x.abs
-}
-
-// SetBits provides raw (unchecked but fast) access to z by setting its
-// value to abs, interpreted as a little-endian Word slice, and returning
-// z. The result and abs share the same underlying array.
-// SetBits is intended to support implementation of missing low-level Int
-// functionality outside this package; it should be avoided otherwise.
-func (z *Int) SetBits(abs []Word) *Int {
- z.abs = nat(abs).norm()
- z.neg = false
- return z
-}
-
-// Abs sets z to |x| (the absolute value of x) and returns z.
-func (z *Int) Abs(x *Int) *Int {
- z.Set(x)
- z.neg = false
- return z
-}
-
-// Neg sets z to -x and returns z.
-func (z *Int) Neg(x *Int) *Int {
- z.Set(x)
- z.neg = len(z.abs) > 0 && !z.neg // 0 has no sign
- return z
-}
-
-// Add sets z to the sum x+y and returns z.
-func (z *Int) Add(x, y *Int) *Int {
- neg := x.neg
- if x.neg == y.neg {
- // x + y == x + y
- // (-x) + (-y) == -(x + y)
- z.abs = z.abs.add(x.abs, y.abs)
- } else {
- // x + (-y) == x - y == -(y - x)
- // (-x) + y == y - x == -(x - y)
- if x.abs.cmp(y.abs) >= 0 {
- z.abs = z.abs.sub(x.abs, y.abs)
- } else {
- neg = !neg
- z.abs = z.abs.sub(y.abs, x.abs)
- }
- }
- z.neg = len(z.abs) > 0 && neg // 0 has no sign
- return z
-}
-
-// Sub sets z to the difference x-y and returns z.
-func (z *Int) Sub(x, y *Int) *Int {
- neg := x.neg
- if x.neg != y.neg {
- // x - (-y) == x + y
- // (-x) - y == -(x + y)
- z.abs = z.abs.add(x.abs, y.abs)
- } else {
- // x - y == x - y == -(y - x)
- // (-x) - (-y) == y - x == -(x - y)
- if x.abs.cmp(y.abs) >= 0 {
- z.abs = z.abs.sub(x.abs, y.abs)
- } else {
- neg = !neg
- z.abs = z.abs.sub(y.abs, x.abs)
- }
- }
- z.neg = len(z.abs) > 0 && neg // 0 has no sign
- return z
-}
-
-// Mul sets z to the product x*y and returns z.
-func (z *Int) Mul(x, y *Int) *Int {
- // x * y == x * y
- // x * (-y) == -(x * y)
- // (-x) * y == -(x * y)
- // (-x) * (-y) == x * y
- z.abs = z.abs.mul(x.abs, y.abs)
- z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign
- return z
-}
-
-// MulRange sets z to the product of all integers
-// in the range [a, b] inclusively and returns z.
-// If a > b (empty range), the result is 1.
-func (z *Int) MulRange(a, b int64) *Int {
- switch {
- case a > b:
- return z.SetInt64(1) // empty range
- case a <= 0 && b >= 0:
- return z.SetInt64(0) // range includes 0
- }
- // a <= b && (b < 0 || a > 0)
-
- neg := false
- if a < 0 {
- neg = (b-a)&1 == 0
- a, b = -b, -a
- }
-
- z.abs = z.abs.mulRange(uint64(a), uint64(b))
- z.neg = neg
- return z
-}
-
-// Binomial sets z to the binomial coefficient of (n, k) and returns z.
-func (z *Int) Binomial(n, k int64) *Int {
- // reduce the number of multiplications by reducing k
- if n/2 < k && k <= n {
- k = n - k // Binomial(n, k) == Binomial(n, n-k)
- }
- var a, b Int
- a.MulRange(n-k+1, n)
- b.MulRange(1, k)
- return z.Quo(&a, &b)
-}
-
-// Quo sets z to the quotient x/y for y != 0 and returns z.
-// If y == 0, a division-by-zero run-time panic occurs.
-// Quo implements truncated division (like Go); see QuoRem for more details.
-func (z *Int) Quo(x, y *Int) *Int {
- z.abs, _ = z.abs.div(nil, x.abs, y.abs)
- z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign
- return z
-}
-
-// Rem sets z to the remainder x%y for y != 0 and returns z.
-// If y == 0, a division-by-zero run-time panic occurs.
-// Rem implements truncated modulus (like Go); see QuoRem for more details.
-func (z *Int) Rem(x, y *Int) *Int {
- _, z.abs = nat(nil).div(z.abs, x.abs, y.abs)
- z.neg = len(z.abs) > 0 && x.neg // 0 has no sign
- return z
-}
-
-// QuoRem sets z to the quotient x/y and r to the remainder x%y
-// and returns the pair (z, r) for y != 0.
-// If y == 0, a division-by-zero run-time panic occurs.
-//
-// QuoRem implements T-division and modulus (like Go):
-//
-// q = x/y with the result truncated to zero
-// r = x - y*q
-//
-// (See Daan Leijen, ``Division and Modulus for Computer Scientists''.)
-// See DivMod for Euclidean division and modulus (unlike Go).
-//
-func (z *Int) QuoRem(x, y, r *Int) (*Int, *Int) {
- z.abs, r.abs = z.abs.div(r.abs, x.abs, y.abs)
- z.neg, r.neg = len(z.abs) > 0 && x.neg != y.neg, len(r.abs) > 0 && x.neg // 0 has no sign
- return z, r
-}
-
-// Div sets z to the quotient x/y for y != 0 and returns z.
-// If y == 0, a division-by-zero run-time panic occurs.
-// Div implements Euclidean division (unlike Go); see DivMod for more details.
-func (z *Int) Div(x, y *Int) *Int {
- y_neg := y.neg // z may be an alias for y
- var r Int
- z.QuoRem(x, y, &r)
- if r.neg {
- if y_neg {
- z.Add(z, intOne)
- } else {
- z.Sub(z, intOne)
- }
- }
- return z
-}
-
-// Mod sets z to the modulus x%y for y != 0 and returns z.
-// If y == 0, a division-by-zero run-time panic occurs.
-// Mod implements Euclidean modulus (unlike Go); see DivMod for more details.
-func (z *Int) Mod(x, y *Int) *Int {
- y0 := y // save y
- if z == y || alias(z.abs, y.abs) {
- y0 = new(Int).Set(y)
- }
- var q Int
- q.QuoRem(x, y, z)
- if z.neg {
- if y0.neg {
- z.Sub(z, y0)
- } else {
- z.Add(z, y0)
- }
- }
- return z
-}
-
-// DivMod sets z to the quotient x div y and m to the modulus x mod y
-// and returns the pair (z, m) for y != 0.
-// If y == 0, a division-by-zero run-time panic occurs.
-//
-// DivMod implements Euclidean division and modulus (unlike Go):
-//
-// q = x div y such that
-// m = x - y*q with 0 <= m < |y|
-//
-// (See Raymond T. Boute, ``The Euclidean definition of the functions
-// div and mod''. ACM Transactions on Programming Languages and
-// Systems (TOPLAS), 14(2):127-144, New York, NY, USA, 4/1992.
-// ACM press.)
-// See QuoRem for T-division and modulus (like Go).
-//
-func (z *Int) DivMod(x, y, m *Int) (*Int, *Int) {
- y0 := y // save y
- if z == y || alias(z.abs, y.abs) {
- y0 = new(Int).Set(y)
- }
- z.QuoRem(x, y, m)
- if m.neg {
- if y0.neg {
- z.Add(z, intOne)
- m.Sub(m, y0)
- } else {
- z.Sub(z, intOne)
- m.Add(m, y0)
- }
- }
- return z, m
-}
-
-// Cmp compares x and y and returns:
-//
-// -1 if x < y
-// 0 if x == y
-// +1 if x > y
-//
-func (x *Int) Cmp(y *Int) (r int) {
- // x cmp y == x cmp y
- // x cmp (-y) == x
- // (-x) cmp y == y
- // (-x) cmp (-y) == -(x cmp y)
- switch {
- case x.neg == y.neg:
- r = x.abs.cmp(y.abs)
- if x.neg {
- r = -r
- }
- case x.neg:
- r = -1
- default:
- r = 1
- }
- return
-}
-
-// low32 returns the least significant 32 bits of z.
-func low32(z nat) uint32 {
- if len(z) == 0 {
- return 0
- }
- return uint32(z[0])
-}
-
-// low64 returns the least significant 64 bits of z.
-func low64(z nat) uint64 {
- if len(z) == 0 {
- return 0
- }
- v := uint64(z[0])
- if _W == 32 && len(z) > 1 {
- v |= uint64(z[1]) << 32
- }
- return v
-}
-
-// Int64 returns the int64 representation of x.
-// If x cannot be represented in an int64, the result is undefined.
-func (x *Int) Int64() int64 {
- v := int64(low64(x.abs))
- if x.neg {
- v = -v
- }
- return v
-}
-
-// Uint64 returns the uint64 representation of x.
-// If x cannot be represented in a uint64, the result is undefined.
-func (x *Int) Uint64() uint64 {
- return low64(x.abs)
-}
-
-// SetString sets z to the value of s, interpreted in the given base,
-// and returns z and a boolean indicating success. If SetString fails,
-// the value of z is undefined but the returned value is nil.
-//
-// The base argument must be 0 or a value between 2 and MaxBase. If the base
-// is 0, the string prefix determines the actual conversion base. A prefix of
-// ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a
-// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
-//
-func (z *Int) SetString(s string, base int) (*Int, bool) {
- r := strings.NewReader(s)
- _, _, err := z.scan(r, base)
- if err != nil {
- return nil, false
- }
- _, err = r.ReadByte()
- if err != io.EOF {
- return nil, false
- }
- return z, true // err == io.EOF => scan consumed all of s
-}
-
-// SetBytes interprets buf as the bytes of a big-endian unsigned
-// integer, sets z to that value, and returns z.
-func (z *Int) SetBytes(buf []byte) *Int {
- z.abs = z.abs.setBytes(buf)
- z.neg = false
- return z
-}
-
-// Bytes returns the absolute value of x as a big-endian byte slice.
-func (x *Int) Bytes() []byte {
- buf := make([]byte, len(x.abs)*_S)
- return buf[x.abs.bytes(buf):]
-}
-
-// BitLen returns the length of the absolute value of x in bits.
-// The bit length of 0 is 0.
-func (x *Int) BitLen() int {
- return x.abs.bitLen()
-}
-
-// 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.
-// See Knuth, volume 2, section 4.6.3.
-func (z *Int) Exp(x, y, m *Int) *Int {
- var yWords nat
- if !y.neg {
- yWords = y.abs
- }
- // y >= 0
-
- 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.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
- z.abs = z.abs.sub(mWords, z.abs) // z == x**y mod |m| && 0 <= z < |m|
- z.neg = false
- }
-
- return z
-}
-
-// GCD sets z to the greatest common divisor of a and b, which both must
-// be > 0, and returns z.
-// If x and y are not nil, GCD sets x and y such that z = a*x + b*y.
-// If either a or b is <= 0, GCD sets z = x = y = 0.
-func (z *Int) GCD(x, y, a, b *Int) *Int {
- if a.Sign() <= 0 || b.Sign() <= 0 {
- z.SetInt64(0)
- if x != nil {
- x.SetInt64(0)
- }
- if y != nil {
- y.SetInt64(0)
- }
- return z
- }
- if x == nil && y == nil {
- return z.binaryGCD(a, b)
- }
-
- A := new(Int).Set(a)
- B := new(Int).Set(b)
-
- X := new(Int)
- Y := new(Int).SetInt64(1)
-
- lastX := new(Int).SetInt64(1)
- lastY := new(Int)
-
- q := new(Int)
- temp := new(Int)
-
- r := new(Int)
- for len(B.abs) > 0 {
- q, r = q.QuoRem(A, B, r)
-
- A, B, r = B, r, A
-
- temp.Set(X)
- X.Mul(X, q)
- X.neg = !X.neg
- X.Add(X, lastX)
- lastX.Set(temp)
-
- temp.Set(Y)
- Y.Mul(Y, q)
- Y.neg = !Y.neg
- Y.Add(Y, lastY)
- lastY.Set(temp)
- }
-
- if x != nil {
- *x = *lastX
- }
-
- if y != nil {
- *y = *lastY
- }
-
- *z = *A
- return z
-}
-
-// binaryGCD sets z to the greatest common divisor of a and b, which both must
-// be > 0, and returns z.
-// See Knuth, The Art of Computer Programming, Vol. 2, Section 4.5.2, Algorithm B.
-func (z *Int) binaryGCD(a, b *Int) *Int {
- u := z
- v := new(Int)
-
- // use one Euclidean iteration to ensure that u and v are approx. the same size
- switch {
- case len(a.abs) > len(b.abs):
- // must set v before u since u may be alias for a or b (was issue #11284)
- v.Rem(a, b)
- u.Set(b)
- case len(a.abs) < len(b.abs):
- v.Rem(b, a)
- u.Set(a)
- default:
- v.Set(b)
- u.Set(a)
- }
- // a, b must not be used anymore (may be aliases with u)
-
- // v might be 0 now
- if len(v.abs) == 0 {
- return u
- }
- // u > 0 && v > 0
-
- // determine largest k such that u = u' << k, v = v' << k
- k := u.abs.trailingZeroBits()
- if vk := v.abs.trailingZeroBits(); vk < k {
- k = vk
- }
- u.Rsh(u, k)
- v.Rsh(v, k)
-
- // determine t (we know that u > 0)
- t := new(Int)
- if u.abs[0]&1 != 0 {
- // u is odd
- t.Neg(v)
- } else {
- t.Set(u)
- }
-
- for len(t.abs) > 0 {
- // reduce t
- t.Rsh(t, t.abs.trailingZeroBits())
- if t.neg {
- v, t = t, v
- v.neg = len(v.abs) > 0 && !v.neg // 0 has no sign
- } else {
- u, t = t, u
- }
- t.Sub(u, v)
- }
-
- return z.Lsh(u, k)
-}
-
-// ProbablyPrime performs n Miller-Rabin tests to check whether x is prime.
-// If x is prime, it returns true.
-// If x is not prime, it returns false with probability at least 1 - ¼ⁿ.
-//
-// It is not suitable for judging primes that an adversary may have crafted
-// to fool this test.
-func (x *Int) ProbablyPrime(n int) bool {
- if n <= 0 {
- panic("non-positive n for ProbablyPrime")
- }
- return !x.neg && x.abs.probablyPrime(n)
-}
-
-// Rand sets z to a pseudo-random number in [0, n) and returns z.
-func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int {
- z.neg = false
- if n.neg == true || len(n.abs) == 0 {
- z.abs = nil
- return z
- }
- z.abs = z.abs.random(rnd, n.abs, n.abs.bitLen())
- return z
-}
-
-// 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.
-func (z *Int) ModInverse(g, n *Int) *Int {
- 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)
- }
- return z
-}
-
-// Jacobi returns the Jacobi symbol (x/y), either +1, -1, or 0.
-// The y argument must be an odd integer.
-func Jacobi(x, y *Int) int {
- if len(y.abs) == 0 || y.abs[0]&1 == 0 {
- panic(fmt.Sprintf("big: invalid 2nd argument to Int.Jacobi: need odd integer but got %s", y))
- }
-
- // We use the formulation described in chapter 2, section 2.4,
- // "The Yacas Book of Algorithms":
- // http://yacas.sourceforge.net/Algo.book.pdf
-
- var a, b, c Int
- a.Set(x)
- b.Set(y)
- j := 1
-
- if b.neg {
- if a.neg {
- j = -1
- }
- b.neg = false
- }
-
- for {
- if b.Cmp(intOne) == 0 {
- return j
- }
- if len(a.abs) == 0 {
- return 0
- }
- a.Mod(&a, &b)
- if len(a.abs) == 0 {
- return 0
- }
- // a > 0
-
- // handle factors of 2 in 'a'
- s := a.abs.trailingZeroBits()
- if s&1 != 0 {
- bmod8 := b.abs[0] & 7
- if bmod8 == 3 || bmod8 == 5 {
- j = -j
- }
- }
- c.Rsh(&a, s) // a = 2^s*c
-
- // swap numerator and denominator
- if b.abs[0]&3 == 3 && c.abs[0]&3 == 3 {
- j = -j
- }
- a.Set(&b)
- b.Set(&c)
- }
-}
-
-// modSqrt3Mod4 uses the identity
-// (a^((p+1)/4))^2 mod p
-// == u^(p+1) mod p
-// == u^2 mod p
-// to calculate the square root of any quadratic residue mod p quickly for 3
-// mod 4 primes.
-func (z *Int) modSqrt3Mod4Prime(x, p *Int) *Int {
- z.Set(p) // z = p
- z.Add(z, intOne) // z = p + 1
- z.Rsh(z, 2) // z = (p + 1) / 4
- z.Exp(x, z, p) // z = x^z mod 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 {
- // Break p-1 into s*2^e such that s is odd.
- var s Int
- s.Sub(p, intOne)
- e := s.abs.trailingZeroBits()
- s.Rsh(&s, e)
-
- // find some non-square n
- var n Int
- n.SetInt64(2)
- for Jacobi(&n, p) != -1 {
- n.Add(&n, intOne)
- }
-
- // Core of the Tonelli-Shanks algorithm. Follows the description in
- // section 6 of "Square roots from 1; 24, 51, 10 to Dan Shanks" by Ezra
- // Brown:
- // https://www.maa.org/sites/default/files/pdf/upload_library/22/Polya/07468342.di020786.02p0470a.pdf
- var y, b, g, t Int
- y.Add(&s, intOne)
- y.Rsh(&y, 1)
- y.Exp(x, &y, p) // y = x^((s+1)/2)
- b.Exp(x, &s, p) // b = x^s
- g.Exp(&n, &s, p) // g = n^s
- r := e
- for {
- // find the least m such that ord_p(b) = 2^m
- var m uint
- t.Set(&b)
- for t.Cmp(intOne) != 0 {
- t.Mul(&t, &t).Mod(&t, p)
- m++
- }
-
- if m == 0 {
- return z.Set(&y)
- }
-
- t.SetInt64(0).SetBit(&t, int(r-m-1), 1).Exp(&g, &t, p)
- // t = g^(2^(r-m-1)) mod p
- g.Mul(&t, &t).Mod(&g, p) // g = g^(2^(r-m)) mod p
- y.Mul(&y, &t).Mod(&y, p)
- b.Mul(&b, &g).Mod(&b, p)
- r = m
- }
-}
-
-// ModSqrt sets z to a square root of x mod p if such a square root exists, and
-// returns z. The modulus p must be an odd prime. If x is not a square mod p,
-// ModSqrt leaves z unchanged and returns nil. This function panics if p is
-// not an odd integer.
-func (z *Int) ModSqrt(x, p *Int) *Int {
- switch Jacobi(x, p) {
- case -1:
- return nil // x is not a square mod p
- case 0:
- return z.SetInt64(0) // sqrt(0) mod p = 0
- case 1:
- break
- }
- if x.neg || x.Cmp(p) >= 0 { // ensure 0 <= x < p
- 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 {
- return z.modSqrt3Mod4Prime(x, p)
- }
- // Otherwise, use Tonelli-Shanks.
- return z.modSqrtTonelliShanks(x, p)
-}
-
-// Lsh sets z = x << n and returns z.
-func (z *Int) Lsh(x *Int, n uint) *Int {
- z.abs = z.abs.shl(x.abs, n)
- z.neg = x.neg
- return z
-}
-
-// Rsh sets z = x >> n and returns z.
-func (z *Int) Rsh(x *Int, n uint) *Int {
- if x.neg {
- // (-x) >> s == ^(x-1) >> s == ^((x-1) >> s) == -(((x-1) >> s) + 1)
- t := z.abs.sub(x.abs, natOne) // no underflow because |x| > 0
- t = t.shr(t, n)
- z.abs = t.add(t, natOne)
- z.neg = true // z cannot be zero if x is negative
- return z
- }
-
- z.abs = z.abs.shr(x.abs, n)
- z.neg = false
- return z
-}
-
-// Bit returns the value of the i'th bit of x. That is, it
-// returns (x>>i)&1. The bit index i must be >= 0.
-func (x *Int) Bit(i int) uint {
- if i == 0 {
- // optimization for common case: odd/even test of x
- if len(x.abs) > 0 {
- return uint(x.abs[0] & 1) // bit 0 is same for -x
- }
- return 0
- }
- if i < 0 {
- panic("negative bit index")
- }
- if x.neg {
- t := nat(nil).sub(x.abs, natOne)
- return t.bit(uint(i)) ^ 1
- }
-
- return x.abs.bit(uint(i))
-}
-
-// SetBit sets z to x, with x's i'th bit set to b (0 or 1).
-// That is, if b is 1 SetBit sets z = x | (1 << i);
-// if b is 0 SetBit sets z = x &^ (1 << i). If b is not 0 or 1,
-// SetBit will panic.
-func (z *Int) SetBit(x *Int, i int, b uint) *Int {
- if i < 0 {
- panic("negative bit index")
- }
- if x.neg {
- t := z.abs.sub(x.abs, natOne)
- t = t.setBit(t, uint(i), b^1)
- z.abs = t.add(t, natOne)
- z.neg = len(z.abs) > 0
- return z
- }
- z.abs = z.abs.setBit(x.abs, uint(i), b)
- z.neg = false
- return z
-}
-
-// And sets z = x & y and returns z.
-func (z *Int) And(x, y *Int) *Int {
- if x.neg == y.neg {
- if x.neg {
- // (-x) & (-y) == ^(x-1) & ^(y-1) == ^((x-1) | (y-1)) == -(((x-1) | (y-1)) + 1)
- x1 := nat(nil).sub(x.abs, natOne)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.add(z.abs.or(x1, y1), natOne)
- z.neg = true // z cannot be zero if x and y are negative
- return z
- }
-
- // x & y == x & y
- z.abs = z.abs.and(x.abs, y.abs)
- z.neg = false
- return z
- }
-
- // x.neg != y.neg
- if x.neg {
- x, y = y, x // & is symmetric
- }
-
- // x & (-y) == x & ^(y-1) == x &^ (y-1)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.andNot(x.abs, y1)
- z.neg = false
- return z
-}
-
-// AndNot sets z = x &^ y and returns z.
-func (z *Int) AndNot(x, y *Int) *Int {
- if x.neg == y.neg {
- if x.neg {
- // (-x) &^ (-y) == ^(x-1) &^ ^(y-1) == ^(x-1) & (y-1) == (y-1) &^ (x-1)
- x1 := nat(nil).sub(x.abs, natOne)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.andNot(y1, x1)
- z.neg = false
- return z
- }
-
- // x &^ y == x &^ y
- z.abs = z.abs.andNot(x.abs, y.abs)
- z.neg = false
- return z
- }
-
- if x.neg {
- // (-x) &^ y == ^(x-1) &^ y == ^(x-1) & ^y == ^((x-1) | y) == -(((x-1) | y) + 1)
- x1 := nat(nil).sub(x.abs, natOne)
- z.abs = z.abs.add(z.abs.or(x1, y.abs), natOne)
- z.neg = true // z cannot be zero if x is negative and y is positive
- return z
- }
-
- // x &^ (-y) == x &^ ^(y-1) == x & (y-1)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.and(x.abs, y1)
- z.neg = false
- return z
-}
-
-// Or sets z = x | y and returns z.
-func (z *Int) Or(x, y *Int) *Int {
- if x.neg == y.neg {
- if x.neg {
- // (-x) | (-y) == ^(x-1) | ^(y-1) == ^((x-1) & (y-1)) == -(((x-1) & (y-1)) + 1)
- x1 := nat(nil).sub(x.abs, natOne)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.add(z.abs.and(x1, y1), natOne)
- z.neg = true // z cannot be zero if x and y are negative
- return z
- }
-
- // x | y == x | y
- z.abs = z.abs.or(x.abs, y.abs)
- z.neg = false
- return z
- }
-
- // x.neg != y.neg
- if x.neg {
- x, y = y, x // | is symmetric
- }
-
- // x | (-y) == x | ^(y-1) == ^((y-1) &^ x) == -(^((y-1) &^ x) + 1)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.add(z.abs.andNot(y1, x.abs), natOne)
- z.neg = true // z cannot be zero if one of x or y is negative
- return z
-}
-
-// Xor sets z = x ^ y and returns z.
-func (z *Int) Xor(x, y *Int) *Int {
- if x.neg == y.neg {
- if x.neg {
- // (-x) ^ (-y) == ^(x-1) ^ ^(y-1) == (x-1) ^ (y-1)
- x1 := nat(nil).sub(x.abs, natOne)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.xor(x1, y1)
- z.neg = false
- return z
- }
-
- // x ^ y == x ^ y
- z.abs = z.abs.xor(x.abs, y.abs)
- z.neg = false
- return z
- }
-
- // x.neg != y.neg
- if x.neg {
- x, y = y, x // ^ is symmetric
- }
-
- // x ^ (-y) == x ^ ^(y-1) == ^(x ^ (y-1)) == -((x ^ (y-1)) + 1)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.add(z.abs.xor(x.abs, y1), natOne)
- z.neg = true // z cannot be zero if only one of x or y is negative
- return z
-}
-
-// Not sets z = ^x and returns z.
-func (z *Int) Not(x *Int) *Int {
- if x.neg {
- // ^(-x) == ^(^(x-1)) == x-1
- z.abs = z.abs.sub(x.abs, natOne)
- z.neg = false
- return z
- }
-
- // ^x == -x-1 == -(x+1)
- z.abs = z.abs.add(x.abs, natOne)
- z.neg = true // z cannot be zero if x is positive
- return z
-}
diff --git a/src/cmd/compile/internal/big/int_test.go b/src/cmd/compile/internal/big/int_test.go
deleted file mode 100644
index 45a3765..0000000
--- a/src/cmd/compile/internal/big/int_test.go
+++ /dev/null
@@ -1,1482 +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 big
-
-import (
- "bytes"
- "encoding/hex"
- "fmt"
- "math/rand"
- "testing"
- "testing/quick"
-)
-
-func isNormalized(x *Int) bool {
- if len(x.abs) == 0 {
- return !x.neg
- }
- // len(x.abs) > 0
- return x.abs[len(x.abs)-1] != 0
-}
-
-type funZZ func(z, x, y *Int) *Int
-type argZZ struct {
- z, x, y *Int
-}
-
-var sumZZ = []argZZ{
- {NewInt(0), NewInt(0), NewInt(0)},
- {NewInt(1), NewInt(1), NewInt(0)},
- {NewInt(1111111110), NewInt(123456789), NewInt(987654321)},
- {NewInt(-1), NewInt(-1), NewInt(0)},
- {NewInt(864197532), NewInt(-123456789), NewInt(987654321)},
- {NewInt(-1111111110), NewInt(-123456789), NewInt(-987654321)},
-}
-
-var prodZZ = []argZZ{
- {NewInt(0), NewInt(0), NewInt(0)},
- {NewInt(0), NewInt(1), NewInt(0)},
- {NewInt(1), NewInt(1), NewInt(1)},
- {NewInt(-991 * 991), NewInt(991), NewInt(-991)},
- // TODO(gri) add larger products
-}
-
-func TestSignZ(t *testing.T) {
- var zero Int
- for _, a := range sumZZ {
- s := a.z.Sign()
- e := a.z.Cmp(&zero)
- if s != e {
- t.Errorf("got %d; want %d for z = %v", s, e, a.z)
- }
- }
-}
-
-func TestSetZ(t *testing.T) {
- for _, a := range sumZZ {
- var z Int
- z.Set(a.z)
- if !isNormalized(&z) {
- t.Errorf("%v is not normalized", z)
- }
- if (&z).Cmp(a.z) != 0 {
- t.Errorf("got z = %v; want %v", z, a.z)
- }
- }
-}
-
-func TestAbsZ(t *testing.T) {
- var zero Int
- for _, a := range sumZZ {
- var z Int
- z.Abs(a.z)
- var e Int
- e.Set(a.z)
- if e.Cmp(&zero) < 0 {
- e.Sub(&zero, &e)
- }
- if z.Cmp(&e) != 0 {
- t.Errorf("got z = %v; want %v", z, e)
- }
- }
-}
-
-func testFunZZ(t *testing.T, msg string, f funZZ, a argZZ) {
- var z Int
- f(&z, a.x, a.y)
- if !isNormalized(&z) {
- t.Errorf("%s%v is not normalized", msg, z)
- }
- if (&z).Cmp(a.z) != 0 {
- t.Errorf("%s%+v\n\tgot z = %v; want %v", msg, a, &z, a.z)
- }
-}
-
-func TestSumZZ(t *testing.T) {
- AddZZ := func(z, x, y *Int) *Int { return z.Add(x, y) }
- SubZZ := func(z, x, y *Int) *Int { return z.Sub(x, y) }
- for _, a := range sumZZ {
- arg := a
- testFunZZ(t, "AddZZ", AddZZ, arg)
-
- arg = argZZ{a.z, a.y, a.x}
- testFunZZ(t, "AddZZ symmetric", AddZZ, arg)
-
- arg = argZZ{a.x, a.z, a.y}
- testFunZZ(t, "SubZZ", SubZZ, arg)
-
- arg = argZZ{a.y, a.z, a.x}
- testFunZZ(t, "SubZZ symmetric", SubZZ, arg)
- }
-}
-
-func TestProdZZ(t *testing.T) {
- MulZZ := func(z, x, y *Int) *Int { return z.Mul(x, y) }
- for _, a := range prodZZ {
- arg := a
- testFunZZ(t, "MulZZ", MulZZ, arg)
-
- arg = argZZ{a.z, a.y, a.x}
- testFunZZ(t, "MulZZ symmetric", MulZZ, arg)
- }
-}
-
-// mulBytes returns x*y via grade school multiplication. Both inputs
-// and the result are assumed to be in big-endian representation (to
-// match the semantics of Int.Bytes and Int.SetBytes).
-func mulBytes(x, y []byte) []byte {
- z := make([]byte, len(x)+len(y))
-
- // multiply
- k0 := len(z) - 1
- for j := len(y) - 1; j >= 0; j-- {
- d := int(y[j])
- if d != 0 {
- k := k0
- carry := 0
- for i := len(x) - 1; i >= 0; i-- {
- t := int(z[k]) + int(x[i])*d + carry
- z[k], carry = byte(t), t>>8
- k--
- }
- z[k] = byte(carry)
- }
- k0--
- }
-
- // normalize (remove leading 0's)
- i := 0
- for i < len(z) && z[i] == 0 {
- i++
- }
-
- return z[i:]
-}
-
-func checkMul(a, b []byte) bool {
- var x, y, z1 Int
- x.SetBytes(a)
- y.SetBytes(b)
- z1.Mul(&x, &y)
-
- var z2 Int
- z2.SetBytes(mulBytes(a, b))
-
- return z1.Cmp(&z2) == 0
-}
-
-func TestMul(t *testing.T) {
- if err := quick.Check(checkMul, nil); err != nil {
- t.Error(err)
- }
-}
-
-var mulRangesZ = []struct {
- a, b int64
- prod string
-}{
- // entirely positive ranges are covered by mulRangesN
- {-1, 1, "0"},
- {-2, -1, "2"},
- {-3, -2, "6"},
- {-3, -1, "-6"},
- {1, 3, "6"},
- {-10, -10, "-10"},
- {0, -1, "1"}, // empty range
- {-1, -100, "1"}, // empty range
- {-1, 1, "0"}, // range includes 0
- {-1e9, 0, "0"}, // range includes 0
- {-1e9, 1e9, "0"}, // range includes 0
- {-10, -1, "3628800"}, // 10!
- {-20, -2, "-2432902008176640000"}, // -20!
- {-99, -1,
- "-933262154439441526816992388562667004907159682643816214685929" +
- "638952175999932299156089414639761565182862536979208272237582" +
- "511852109168640000000000000000000000", // -99!
- },
-}
-
-func TestMulRangeZ(t *testing.T) {
- var tmp Int
- // test entirely positive ranges
- for i, r := range mulRangesN {
- prod := tmp.MulRange(int64(r.a), int64(r.b)).String()
- if prod != r.prod {
- t.Errorf("#%da: got %s; want %s", i, prod, r.prod)
- }
- }
- // test other ranges
- for i, r := range mulRangesZ {
- prod := tmp.MulRange(r.a, r.b).String()
- if prod != r.prod {
- t.Errorf("#%db: got %s; want %s", i, prod, r.prod)
- }
- }
-}
-
-func TestBinomial(t *testing.T) {
- var z Int
- for _, test := range []struct {
- n, k int64
- want string
- }{
- {0, 0, "1"},
- {0, 1, "0"},
- {1, 0, "1"},
- {1, 1, "1"},
- {1, 10, "0"},
- {4, 0, "1"},
- {4, 1, "4"},
- {4, 2, "6"},
- {4, 3, "4"},
- {4, 4, "1"},
- {10, 1, "10"},
- {10, 9, "10"},
- {10, 5, "252"},
- {11, 5, "462"},
- {11, 6, "462"},
- {100, 10, "17310309456440"},
- {100, 90, "17310309456440"},
- {1000, 10, "263409560461970212832400"},
- {1000, 990, "263409560461970212832400"},
- } {
- if got := z.Binomial(test.n, test.k).String(); got != test.want {
- t.Errorf("Binomial(%d, %d) = %s; want %s", test.n, test.k, got, test.want)
- }
- }
-}
-
-func BenchmarkBinomial(b *testing.B) {
- var z Int
- for i := b.N - 1; i >= 0; i-- {
- z.Binomial(1000, 990)
- }
-}
-
-// Examples from the Go Language Spec, section "Arithmetic operators"
-var divisionSignsTests = []struct {
- x, y int64
- q, r int64 // T-division
- d, m int64 // Euclidian division
-}{
- {5, 3, 1, 2, 1, 2},
- {-5, 3, -1, -2, -2, 1},
- {5, -3, -1, 2, -1, 2},
- {-5, -3, 1, -2, 2, 1},
- {1, 2, 0, 1, 0, 1},
- {8, 4, 2, 0, 2, 0},
-}
-
-func TestDivisionSigns(t *testing.T) {
- for i, test := range divisionSignsTests {
- x := NewInt(test.x)
- y := NewInt(test.y)
- q := NewInt(test.q)
- r := NewInt(test.r)
- d := NewInt(test.d)
- m := NewInt(test.m)
-
- q1 := new(Int).Quo(x, y)
- r1 := new(Int).Rem(x, y)
- if !isNormalized(q1) {
- t.Errorf("#%d Quo: %v is not normalized", i, *q1)
- }
- if !isNormalized(r1) {
- t.Errorf("#%d Rem: %v is not normalized", i, *r1)
- }
- if q1.Cmp(q) != 0 || r1.Cmp(r) != 0 {
- t.Errorf("#%d QuoRem: got (%s, %s), want (%s, %s)", i, q1, r1, q, r)
- }
-
- q2, r2 := new(Int).QuoRem(x, y, new(Int))
- if !isNormalized(q2) {
- t.Errorf("#%d Quo: %v is not normalized", i, *q2)
- }
- if !isNormalized(r2) {
- t.Errorf("#%d Rem: %v is not normalized", i, *r2)
- }
- if q2.Cmp(q) != 0 || r2.Cmp(r) != 0 {
- t.Errorf("#%d QuoRem: got (%s, %s), want (%s, %s)", i, q2, r2, q, r)
- }
-
- d1 := new(Int).Div(x, y)
- m1 := new(Int).Mod(x, y)
- if !isNormalized(d1) {
- t.Errorf("#%d Div: %v is not normalized", i, *d1)
- }
- if !isNormalized(m1) {
- t.Errorf("#%d Mod: %v is not normalized", i, *m1)
- }
- if d1.Cmp(d) != 0 || m1.Cmp(m) != 0 {
- t.Errorf("#%d DivMod: got (%s, %s), want (%s, %s)", i, d1, m1, d, m)
- }
-
- d2, m2 := new(Int).DivMod(x, y, new(Int))
- if !isNormalized(d2) {
- t.Errorf("#%d Div: %v is not normalized", i, *d2)
- }
- if !isNormalized(m2) {
- t.Errorf("#%d Mod: %v is not normalized", i, *m2)
- }
- if d2.Cmp(d) != 0 || m2.Cmp(m) != 0 {
- t.Errorf("#%d DivMod: got (%s, %s), want (%s, %s)", i, d2, m2, d, m)
- }
- }
-}
-
-func norm(x nat) nat {
- i := len(x)
- for i > 0 && x[i-1] == 0 {
- i--
- }
- return x[:i]
-}
-
-func TestBits(t *testing.T) {
- for _, test := range []nat{
- nil,
- {0},
- {1},
- {0, 1, 2, 3, 4},
- {4, 3, 2, 1, 0},
- {4, 3, 2, 1, 0, 0, 0, 0},
- } {
- var z Int
- z.neg = true
- got := z.SetBits(test)
- want := norm(test)
- if got.abs.cmp(want) != 0 {
- t.Errorf("SetBits(%v) = %v; want %v", test, got.abs, want)
- }
-
- if got.neg {
- t.Errorf("SetBits(%v): got negative result", test)
- }
-
- bits := nat(z.Bits())
- if bits.cmp(want) != 0 {
- t.Errorf("%v.Bits() = %v; want %v", z.abs, bits, want)
- }
- }
-}
-
-func checkSetBytes(b []byte) bool {
- hex1 := hex.EncodeToString(new(Int).SetBytes(b).Bytes())
- hex2 := hex.EncodeToString(b)
-
- for len(hex1) < len(hex2) {
- hex1 = "0" + hex1
- }
-
- for len(hex1) > len(hex2) {
- hex2 = "0" + hex2
- }
-
- return hex1 == hex2
-}
-
-func TestSetBytes(t *testing.T) {
- if err := quick.Check(checkSetBytes, nil); err != nil {
- t.Error(err)
- }
-}
-
-func checkBytes(b []byte) bool {
- // trim leading zero bytes since Bytes() won't return them
- // (was issue 12231)
- for len(b) > 0 && b[0] == 0 {
- b = b[1:]
- }
- b2 := new(Int).SetBytes(b).Bytes()
- return bytes.Equal(b, b2)
-}
-
-func TestBytes(t *testing.T) {
- if err := quick.Check(checkBytes, nil); err != nil {
- t.Error(err)
- }
-}
-
-func checkQuo(x, y []byte) bool {
- u := new(Int).SetBytes(x)
- v := new(Int).SetBytes(y)
-
- if len(v.abs) == 0 {
- return true
- }
-
- r := new(Int)
- q, r := new(Int).QuoRem(u, v, r)
-
- if r.Cmp(v) >= 0 {
- return false
- }
-
- uprime := new(Int).Set(q)
- uprime.Mul(uprime, v)
- uprime.Add(uprime, r)
-
- return uprime.Cmp(u) == 0
-}
-
-var quoTests = []struct {
- x, y string
- q, r string
-}{
- {
- "476217953993950760840509444250624797097991362735329973741718102894495832294430498335824897858659711275234906400899559094370964723884706254265559534144986498357",
- "9353930466774385905609975137998169297361893554149986716853295022578535724979483772383667534691121982974895531435241089241440253066816724367338287092081996",
- "50911",
- "1",
- },
- {
- "11510768301994997771168",
- "1328165573307167369775",
- "8",
- "885443715537658812968",
- },
-}
-
-func TestQuo(t *testing.T) {
- if err := quick.Check(checkQuo, nil); err != nil {
- t.Error(err)
- }
-
- for i, test := range quoTests {
- x, _ := new(Int).SetString(test.x, 10)
- y, _ := new(Int).SetString(test.y, 10)
- expectedQ, _ := new(Int).SetString(test.q, 10)
- expectedR, _ := new(Int).SetString(test.r, 10)
-
- r := new(Int)
- q, r := new(Int).QuoRem(x, y, r)
-
- if q.Cmp(expectedQ) != 0 || r.Cmp(expectedR) != 0 {
- t.Errorf("#%d got (%s, %s) want (%s, %s)", i, q, r, expectedQ, expectedR)
- }
- }
-}
-
-func TestQuoStepD6(t *testing.T) {
- // See Knuth, Volume 2, section 4.3.1, exercise 21. This code exercises
- // a code path which only triggers 1 in 10^{-19} cases.
-
- u := &Int{false, nat{0, 0, 1 + 1<<(_W-1), _M ^ (1 << (_W - 1))}}
- v := &Int{false, nat{5, 2 + 1<<(_W-1), 1 << (_W - 1)}}
-
- r := new(Int)
- q, r := new(Int).QuoRem(u, v, r)
- const expectedQ64 = "18446744073709551613"
- const expectedR64 = "3138550867693340382088035895064302439801311770021610913807"
- const expectedQ32 = "4294967293"
- const expectedR32 = "39614081266355540837921718287"
- if q.String() != expectedQ64 && q.String() != expectedQ32 ||
- r.String() != expectedR64 && r.String() != expectedR32 {
- t.Errorf("got (%s, %s) want (%s, %s) or (%s, %s)", q, r, expectedQ64, expectedR64, expectedQ32, expectedR32)
- }
-}
-
-var bitLenTests = []struct {
- in string
- out int
-}{
- {"-1", 1},
- {"0", 0},
- {"1", 1},
- {"2", 2},
- {"4", 3},
- {"0xabc", 12},
- {"0x8000", 16},
- {"0x80000000", 32},
- {"0x800000000000", 48},
- {"0x8000000000000000", 64},
- {"0x80000000000000000000", 80},
- {"-0x4000000000000000000000", 87},
-}
-
-func TestBitLen(t *testing.T) {
- for i, test := range bitLenTests {
- x, ok := new(Int).SetString(test.in, 0)
- if !ok {
- t.Errorf("#%d test input invalid: %s", i, test.in)
- continue
- }
-
- if n := x.BitLen(); n != test.out {
- t.Errorf("#%d got %d want %d", i, n, test.out)
- }
- }
-}
-
-var expTests = []struct {
- x, y, m string
- out string
-}{
- // y <= 0
- {"0", "0", "", "1"},
- {"1", "0", "", "1"},
- {"-10", "0", "", "1"},
- {"1234", "-1", "", "1"},
-
- // m == 1
- {"0", "0", "1", "0"},
- {"1", "0", "1", "0"},
- {"-10", "0", "1", "0"},
- {"1234", "-1", "1", "0"},
-
- // misc
- {"5", "1", "3", "2"},
- {"5", "-7", "", "1"},
- {"-5", "-7", "", "1"},
- {"5", "0", "", "1"},
- {"-5", "0", "", "1"},
- {"5", "1", "", "5"},
- {"-5", "1", "", "-5"},
- {"-5", "1", "7", "2"},
- {"-2", "3", "2", "0"},
- {"5", "2", "", "25"},
- {"1", "65537", "2", "1"},
- {"0x8000000000000000", "2", "", "0x40000000000000000000000000000000"},
- {"0x8000000000000000", "2", "6719", "4944"},
- {"0x8000000000000000", "3", "6719", "5447"},
- {"0x8000000000000000", "1000", "6719", "1603"},
- {"0x8000000000000000", "1000000", "6719", "3199"},
- {"0x8000000000000000", "-1000000", "6719", "1"},
-
- {"0xffffffffffffffffffffffffffffffff", "0x12345678123456781234567812345678123456789", "0x01112222333344445555666677778889", "0x36168FA1DB3AAE6C8CE647E137F97A"},
-
- {
- "2938462938472983472983659726349017249287491026512746239764525612965293865296239471239874193284792387498274256129746192347",
- "298472983472983471903246121093472394872319615612417471234712061",
- "29834729834729834729347290846729561262544958723956495615629569234729836259263598127342374289365912465901365498236492183464",
- "23537740700184054162508175125554701713153216681790245129157191391322321508055833908509185839069455749219131480588829346291",
- },
- // test case for issue 8822
- {
- "11001289118363089646017359372117963499250546375269047542777928006103246876688756735760905680604646624353196869572752623285140408755420374049317646428185270079555372763503115646054602867593662923894140940837479507194934267532831694565516466765025434902348314525627418515646588160955862839022051353653052947073136084780742729727874803457643848197499548297570026926927502505634297079527299004267769780768565695459945235586892627059178884998772989397505061206395455591503771677500931269477503508150175717121828518985901959919560700853226255420793148986854391552859459511723547532575574664944815966793196961286234040892865",
- "0xB08FFB20760FFED58FADA86DFEF71AD72AA0FA763219618FE022C197E54708BB1191C66470250FCE8879487507CEE41381CA4D932F81C2B3F1AB20B539D50DCD",
- "0xAC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73",
- "21484252197776302499639938883777710321993113097987201050501182909581359357618579566746556372589385361683610524730509041328855066514963385522570894839035884713051640171474186548713546686476761306436434146475140156284389181808675016576845833340494848283681088886584219750554408060556769486628029028720727393293111678826356480455433909233520504112074401376133077150471237549474149190242010469539006449596611576612573955754349042329130631128234637924786466585703488460540228477440853493392086251021228087076124706778899179648655221663765993962724699135217212118535057766739392069738618682722216712319320435674779146070442",
- },
- {
- "-0x1BCE04427D8032319A89E5C4136456671AC620883F2C4139E57F91307C485AD2D6204F4F87A58262652DB5DBBAC72B0613E51B835E7153BEC6068F5C8D696B74DBD18FEC316AEF73985CF0475663208EB46B4F17DD9DA55367B03323E5491A70997B90C059FB34809E6EE55BCFBD5F2F52233BFE62E6AA9E4E26A1D4C2439883D14F2633D55D8AA66A1ACD5595E778AC3A280517F1157989E70C1A437B849F1877B779CC3CDDEDE2DAA6594A6C66D181A00A5F777EE60596D8773998F6E988DEAE4CCA60E4DDCF9590543C89F74F603259FCAD71660D30294FBBE6490300F78A9D63FA660DC9417B8B9DDA28BEB3977B621B988E23D4D954F322C3540541BC649ABD504C50FADFD9F0987D58A2BF689313A285E773FF02899A6EF887D1D4A0D2",
- "0xB08FFB20760FFED58FADA86DFEF71AD72AA0FA763219618FE022C197E54708BB1191C66470250FCE8879487507CEE41381CA4D932F81C2B3F1AB20B539D50DCD",
- "0xAC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73",
- "21484252197776302499639938883777710321993113097987201050501182909581359357618579566746556372589385361683610524730509041328855066514963385522570894839035884713051640171474186548713546686476761306436434146475140156284389181808675016576845833340494848283681088886584219750554408060556769486628029028720727393293111678826356480455433909233520504112074401376133077150471237549474149190242010469539006449596611576612573955754349042329130631128234637924786466585703488460540228477440853493392086251021228087076124706778899179648655221663765993962724699135217212118535057766739392069738618682722216712319320435674779146070442",
- },
-
- // test cases for issue 13907
- {"0xffffffff00000001", "0xffffffff00000001", "0xffffffff00000001", "0"},
- {"0xffffffffffffffff00000001", "0xffffffffffffffff00000001", "0xffffffffffffffff00000001", "0"},
- {"0xffffffffffffffffffffffff00000001", "0xffffffffffffffffffffffff00000001", "0xffffffffffffffffffffffff00000001", "0"},
- {"0xffffffffffffffffffffffffffffffff00000001", "0xffffffffffffffffffffffffffffffff00000001", "0xffffffffffffffffffffffffffffffff00000001", "0"},
-}
-
-func TestExp(t *testing.T) {
- for i, test := range expTests {
- x, ok1 := new(Int).SetString(test.x, 0)
- y, ok2 := new(Int).SetString(test.y, 0)
- out, ok3 := new(Int).SetString(test.out, 0)
-
- var ok4 bool
- var m *Int
-
- if len(test.m) == 0 {
- m, ok4 = nil, true
- } else {
- m, ok4 = new(Int).SetString(test.m, 0)
- }
-
- if !ok1 || !ok2 || !ok3 || !ok4 {
- t.Errorf("#%d: error in input", i)
- continue
- }
-
- z1 := new(Int).Exp(x, y, m)
- if !isNormalized(z1) {
- t.Errorf("#%d: %v is not normalized", i, *z1)
- }
- if z1.Cmp(out) != 0 {
- t.Errorf("#%d: got %x want %x", i, z1, out)
- }
-
- if m == nil {
- // The result should be the same as for m == 0;
- // specifically, there should be no div-zero panic.
- m = &Int{abs: nat{}} // m != nil && len(m.abs) == 0
- z2 := new(Int).Exp(x, y, m)
- if z2.Cmp(z1) != 0 {
- t.Errorf("#%d: got %x want %x", i, z2, z1)
- }
- }
- }
-}
-
-func checkGcd(aBytes, bBytes []byte) bool {
- x := new(Int)
- y := new(Int)
- a := new(Int).SetBytes(aBytes)
- b := new(Int).SetBytes(bBytes)
-
- d := new(Int).GCD(x, y, a, b)
- x.Mul(x, a)
- y.Mul(y, b)
- x.Add(x, y)
-
- return x.Cmp(d) == 0
-}
-
-var gcdTests = []struct {
- d, x, y, a, b string
-}{
- // a <= 0 || b <= 0
- {"0", "0", "0", "0", "0"},
- {"0", "0", "0", "0", "7"},
- {"0", "0", "0", "11", "0"},
- {"0", "0", "0", "-77", "35"},
- {"0", "0", "0", "64515", "-24310"},
- {"0", "0", "0", "-64515", "-24310"},
-
- {"1", "-9", "47", "120", "23"},
- {"7", "1", "-2", "77", "35"},
- {"935", "-3", "8", "64515", "24310"},
- {"935000000000000000", "-3", "8", "64515000000000000000", "24310000000000000000"},
- {"1", "-221", "22059940471369027483332068679400581064239780177629666810348940098015901108344", "98920366548084643601728869055592650835572950932266967461790948584315647051443", "991"},
-
- // test early exit (after one Euclidean iteration) in binaryGCD
- {"1", "", "", "1", "98920366548084643601728869055592650835572950932266967461790948584315647051443"},
-}
-
-func testGcd(t *testing.T, d, x, y, a, b *Int) {
- var X *Int
- if x != nil {
- X = new(Int)
- }
- var Y *Int
- if y != nil {
- Y = new(Int)
- }
-
- D := new(Int).GCD(X, Y, a, b)
- if D.Cmp(d) != 0 {
- t.Errorf("GCD(%s, %s): got d = %s, want %s", a, b, D, d)
- }
- if x != nil && X.Cmp(x) != 0 {
- t.Errorf("GCD(%s, %s): got x = %s, want %s", a, b, X, x)
- }
- if y != nil && Y.Cmp(y) != 0 {
- t.Errorf("GCD(%s, %s): got y = %s, want %s", a, b, Y, y)
- }
-
- // binaryGCD requires a > 0 && b > 0
- if a.Sign() <= 0 || b.Sign() <= 0 {
- return
- }
-
- D.binaryGCD(a, b)
- if D.Cmp(d) != 0 {
- t.Errorf("binaryGcd(%s, %s): got d = %s, want %s", a, b, D, d)
- }
-
- // check results in presence of aliasing (issue #11284)
- a2 := new(Int).Set(a)
- b2 := new(Int).Set(b)
- a2.binaryGCD(a2, b2) // result is same as 1st argument
- if a2.Cmp(d) != 0 {
- t.Errorf("binaryGcd(%s, %s): got d = %s, want %s", a, b, a2, d)
- }
-
- a2 = new(Int).Set(a)
- b2 = new(Int).Set(b)
- b2.binaryGCD(a2, b2) // result is same as 2nd argument
- if b2.Cmp(d) != 0 {
- t.Errorf("binaryGcd(%s, %s): got d = %s, want %s", a, b, b2, d)
- }
-}
-
-func TestGcd(t *testing.T) {
- for _, test := range gcdTests {
- d, _ := new(Int).SetString(test.d, 0)
- x, _ := new(Int).SetString(test.x, 0)
- y, _ := new(Int).SetString(test.y, 0)
- a, _ := new(Int).SetString(test.a, 0)
- b, _ := new(Int).SetString(test.b, 0)
-
- testGcd(t, d, nil, nil, a, b)
- testGcd(t, d, x, nil, a, b)
- testGcd(t, d, nil, y, a, b)
- testGcd(t, d, x, y, a, b)
- }
-
- if err := quick.Check(checkGcd, nil); err != nil {
- t.Error(err)
- }
-}
-
-var primes = []string{
- "2",
- "3",
- "5",
- "7",
- "11",
-
- "13756265695458089029",
- "13496181268022124907",
- "10953742525620032441",
- "17908251027575790097",
-
- // https://golang.org/issue/638
- "18699199384836356663",
-
- "98920366548084643601728869055592650835572950932266967461790948584315647051443",
- "94560208308847015747498523884063394671606671904944666360068158221458669711639",
-
- // http://primes.utm.edu/lists/small/small3.html
- "449417999055441493994709297093108513015373787049558499205492347871729927573118262811508386655998299074566974373711472560655026288668094291699357843464363003144674940345912431129144354948751003607115263071543163",
- "230975859993204150666423538988557839555560243929065415434980904258310530753006723857139742334640122533598517597674807096648905501653461687601339782814316124971547968912893214002992086353183070342498989426570593",
- "5521712099665906221540423207019333379125265462121169655563495403888449493493629943498064604536961775110765377745550377067893607246020694972959780839151452457728855382113555867743022746090187341871655890805971735385789993",
- "203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123",
-
- // ECC primes: http://tools.ietf.org/html/draft-ladd-safecurves-02
- "3618502788666131106986593281521497120414687020801267626233049500247285301239", // Curve1174: 2^251-9
- "57896044618658097711785492504343953926634992332820282019728792003956564819949", // Curve25519: 2^255-19
- "9850501549098619803069760025035903451269934817616361666987073351061430442874302652853566563721228910201656997576599", // E-382: 2^382-105
- "42307582002575910332922579714097346549017899709713998034217522897561970639123926132812109468141778230245837569601494931472367", // Curve41417: 2^414-17
- "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", // E-521: 2^521-1
-}
-
-var composites = []string{
- "0",
- "1",
- "21284175091214687912771199898307297748211672914763848041968395774954376176754",
- "6084766654921918907427900243509372380954290099172559290432744450051395395951",
- "84594350493221918389213352992032324280367711247940675652888030554255915464401",
- "82793403787388584738507275144194252681",
-}
-
-func TestProbablyPrime(t *testing.T) {
- nreps := 20
- if testing.Short() {
- nreps = 1
- }
- for i, s := range primes {
- p, _ := new(Int).SetString(s, 10)
- if !p.ProbablyPrime(nreps) {
- t.Errorf("#%d prime found to be non-prime (%s)", i, s)
- }
- }
-
- for i, s := range composites {
- c, _ := new(Int).SetString(s, 10)
- if c.ProbablyPrime(nreps) {
- t.Errorf("#%d composite found to be prime (%s)", i, s)
- }
- if testing.Short() {
- break
- }
- }
-
- // check that ProbablyPrime panics if n <= 0
- c := NewInt(11) // a prime
- for _, n := range []int{-1, 0, 1} {
- func() {
- defer func() {
- if n <= 0 && recover() == nil {
- t.Fatalf("expected panic from ProbablyPrime(%d)", n)
- }
- }()
- if !c.ProbablyPrime(n) {
- t.Fatalf("%v should be a prime", c)
- }
- }()
- }
-}
-
-type intShiftTest struct {
- in string
- shift uint
- out string
-}
-
-var rshTests = []intShiftTest{
- {"0", 0, "0"},
- {"-0", 0, "0"},
- {"0", 1, "0"},
- {"0", 2, "0"},
- {"1", 0, "1"},
- {"1", 1, "0"},
- {"1", 2, "0"},
- {"2", 0, "2"},
- {"2", 1, "1"},
- {"-1", 0, "-1"},
- {"-1", 1, "-1"},
- {"-1", 10, "-1"},
- {"-100", 2, "-25"},
- {"-100", 3, "-13"},
- {"-100", 100, "-1"},
- {"4294967296", 0, "4294967296"},
- {"4294967296", 1, "2147483648"},
- {"4294967296", 2, "1073741824"},
- {"18446744073709551616", 0, "18446744073709551616"},
- {"18446744073709551616", 1, "9223372036854775808"},
- {"18446744073709551616", 2, "4611686018427387904"},
- {"18446744073709551616", 64, "1"},
- {"340282366920938463463374607431768211456", 64, "18446744073709551616"},
- {"340282366920938463463374607431768211456", 128, "1"},
-}
-
-func TestRsh(t *testing.T) {
- for i, test := range rshTests {
- in, _ := new(Int).SetString(test.in, 10)
- expected, _ := new(Int).SetString(test.out, 10)
- out := new(Int).Rsh(in, test.shift)
-
- if !isNormalized(out) {
- t.Errorf("#%d: %v is not normalized", i, *out)
- }
- if out.Cmp(expected) != 0 {
- t.Errorf("#%d: got %s want %s", i, out, expected)
- }
- }
-}
-
-func TestRshSelf(t *testing.T) {
- for i, test := range rshTests {
- z, _ := new(Int).SetString(test.in, 10)
- expected, _ := new(Int).SetString(test.out, 10)
- z.Rsh(z, test.shift)
-
- if !isNormalized(z) {
- t.Errorf("#%d: %v is not normalized", i, *z)
- }
- if z.Cmp(expected) != 0 {
- t.Errorf("#%d: got %s want %s", i, z, expected)
- }
- }
-}
-
-var lshTests = []intShiftTest{
- {"0", 0, "0"},
- {"0", 1, "0"},
- {"0", 2, "0"},
- {"1", 0, "1"},
- {"1", 1, "2"},
- {"1", 2, "4"},
- {"2", 0, "2"},
- {"2", 1, "4"},
- {"2", 2, "8"},
- {"-87", 1, "-174"},
- {"4294967296", 0, "4294967296"},
- {"4294967296", 1, "8589934592"},
- {"4294967296", 2, "17179869184"},
- {"18446744073709551616", 0, "18446744073709551616"},
- {"9223372036854775808", 1, "18446744073709551616"},
- {"4611686018427387904", 2, "18446744073709551616"},
- {"1", 64, "18446744073709551616"},
- {"18446744073709551616", 64, "340282366920938463463374607431768211456"},
- {"1", 128, "340282366920938463463374607431768211456"},
-}
-
-func TestLsh(t *testing.T) {
- for i, test := range lshTests {
- in, _ := new(Int).SetString(test.in, 10)
- expected, _ := new(Int).SetString(test.out, 10)
- out := new(Int).Lsh(in, test.shift)
-
- if !isNormalized(out) {
- t.Errorf("#%d: %v is not normalized", i, *out)
- }
- if out.Cmp(expected) != 0 {
- t.Errorf("#%d: got %s want %s", i, out, expected)
- }
- }
-}
-
-func TestLshSelf(t *testing.T) {
- for i, test := range lshTests {
- z, _ := new(Int).SetString(test.in, 10)
- expected, _ := new(Int).SetString(test.out, 10)
- z.Lsh(z, test.shift)
-
- if !isNormalized(z) {
- t.Errorf("#%d: %v is not normalized", i, *z)
- }
- if z.Cmp(expected) != 0 {
- t.Errorf("#%d: got %s want %s", i, z, expected)
- }
- }
-}
-
-func TestLshRsh(t *testing.T) {
- for i, test := range rshTests {
- in, _ := new(Int).SetString(test.in, 10)
- out := new(Int).Lsh(in, test.shift)
- out = out.Rsh(out, test.shift)
-
- if !isNormalized(out) {
- t.Errorf("#%d: %v is not normalized", i, *out)
- }
- if in.Cmp(out) != 0 {
- t.Errorf("#%d: got %s want %s", i, out, in)
- }
- }
- for i, test := range lshTests {
- in, _ := new(Int).SetString(test.in, 10)
- out := new(Int).Lsh(in, test.shift)
- out.Rsh(out, test.shift)
-
- if !isNormalized(out) {
- t.Errorf("#%d: %v is not normalized", i, *out)
- }
- if in.Cmp(out) != 0 {
- t.Errorf("#%d: got %s want %s", i, out, in)
- }
- }
-}
-
-var int64Tests = []int64{
- 0,
- 1,
- -1,
- 4294967295,
- -4294967295,
- 4294967296,
- -4294967296,
- 9223372036854775807,
- -9223372036854775807,
- -9223372036854775808,
-}
-
-func TestInt64(t *testing.T) {
- for i, testVal := range int64Tests {
- in := NewInt(testVal)
- out := in.Int64()
-
- if out != testVal {
- t.Errorf("#%d got %d want %d", i, out, testVal)
- }
- }
-}
-
-var uint64Tests = []uint64{
- 0,
- 1,
- 4294967295,
- 4294967296,
- 8589934591,
- 8589934592,
- 9223372036854775807,
- 9223372036854775808,
- 18446744073709551615, // 1<<64 - 1
-}
-
-func TestUint64(t *testing.T) {
- in := new(Int)
- for i, testVal := range uint64Tests {
- in.SetUint64(testVal)
- out := in.Uint64()
-
- if out != testVal {
- t.Errorf("#%d got %d want %d", i, out, testVal)
- }
-
- str := fmt.Sprint(testVal)
- strOut := in.String()
- if strOut != str {
- t.Errorf("#%d.String got %s want %s", i, strOut, str)
- }
- }
-}
-
-var bitwiseTests = []struct {
- x, y string
- and, or, xor, andNot string
-}{
- {"0x00", "0x00", "0x00", "0x00", "0x00", "0x00"},
- {"0x00", "0x01", "0x00", "0x01", "0x01", "0x00"},
- {"0x01", "0x00", "0x00", "0x01", "0x01", "0x01"},
- {"-0x01", "0x00", "0x00", "-0x01", "-0x01", "-0x01"},
- {"-0xaf", "-0x50", "-0xf0", "-0x0f", "0xe1", "0x41"},
- {"0x00", "-0x01", "0x00", "-0x01", "-0x01", "0x00"},
- {"0x01", "0x01", "0x01", "0x01", "0x00", "0x00"},
- {"-0x01", "-0x01", "-0x01", "-0x01", "0x00", "0x00"},
- {"0x07", "0x08", "0x00", "0x0f", "0x0f", "0x07"},
- {"0x05", "0x0f", "0x05", "0x0f", "0x0a", "0x00"},
- {"0xff", "-0x0a", "0xf6", "-0x01", "-0xf7", "0x09"},
- {"0x013ff6", "0x9a4e", "0x1a46", "0x01bffe", "0x01a5b8", "0x0125b0"},
- {"-0x013ff6", "0x9a4e", "0x800a", "-0x0125b2", "-0x01a5bc", "-0x01c000"},
- {"-0x013ff6", "-0x9a4e", "-0x01bffe", "-0x1a46", "0x01a5b8", "0x8008"},
- {
- "0x1000009dc6e3d9822cba04129bcbe3401",
- "0xb9bd7d543685789d57cb918e833af352559021483cdb05cc21fd",
- "0x1000001186210100001000009048c2001",
- "0xb9bd7d543685789d57cb918e8bfeff7fddb2ebe87dfbbdfe35fd",
- "0xb9bd7d543685789d57ca918e8ae69d6fcdb2eae87df2b97215fc",
- "0x8c40c2d8822caa04120b8321400",
- },
- {
- "0x1000009dc6e3d9822cba04129bcbe3401",
- "-0xb9bd7d543685789d57cb918e833af352559021483cdb05cc21fd",
- "0x8c40c2d8822caa04120b8321401",
- "-0xb9bd7d543685789d57ca918e82229142459020483cd2014001fd",
- "-0xb9bd7d543685789d57ca918e8ae69d6fcdb2eae87df2b97215fe",
- "0x1000001186210100001000009048c2000",
- },
- {
- "-0x1000009dc6e3d9822cba04129bcbe3401",
- "-0xb9bd7d543685789d57cb918e833af352559021483cdb05cc21fd",
- "-0xb9bd7d543685789d57cb918e8bfeff7fddb2ebe87dfbbdfe35fd",
- "-0x1000001186210100001000009048c2001",
- "0xb9bd7d543685789d57ca918e8ae69d6fcdb2eae87df2b97215fc",
- "0xb9bd7d543685789d57ca918e82229142459020483cd2014001fc",
- },
-}
-
-type bitFun func(z, x, y *Int) *Int
-
-func testBitFun(t *testing.T, msg string, f bitFun, x, y *Int, exp string) {
- expected := new(Int)
- expected.SetString(exp, 0)
-
- out := f(new(Int), x, y)
- if out.Cmp(expected) != 0 {
- t.Errorf("%s: got %s want %s", msg, out, expected)
- }
-}
-
-func testBitFunSelf(t *testing.T, msg string, f bitFun, x, y *Int, exp string) {
- self := new(Int)
- self.Set(x)
- expected := new(Int)
- expected.SetString(exp, 0)
-
- self = f(self, self, y)
- if self.Cmp(expected) != 0 {
- t.Errorf("%s: got %s want %s", msg, self, expected)
- }
-}
-
-func altBit(x *Int, i int) uint {
- z := new(Int).Rsh(x, uint(i))
- z = z.And(z, NewInt(1))
- if z.Cmp(new(Int)) != 0 {
- return 1
- }
- return 0
-}
-
-func altSetBit(z *Int, x *Int, i int, b uint) *Int {
- one := NewInt(1)
- m := one.Lsh(one, uint(i))
- switch b {
- case 1:
- return z.Or(x, m)
- case 0:
- return z.AndNot(x, m)
- }
- panic("set bit is not 0 or 1")
-}
-
-func testBitset(t *testing.T, x *Int) {
- n := x.BitLen()
- z := new(Int).Set(x)
- z1 := new(Int).Set(x)
- for i := 0; i < n+10; i++ {
- old := z.Bit(i)
- old1 := altBit(z1, i)
- if old != old1 {
- t.Errorf("bitset: inconsistent value for Bit(%s, %d), got %v want %v", z1, i, old, old1)
- }
- z := new(Int).SetBit(z, i, 1)
- z1 := altSetBit(new(Int), z1, i, 1)
- if z.Bit(i) == 0 {
- t.Errorf("bitset: bit %d of %s got 0 want 1", i, x)
- }
- if z.Cmp(z1) != 0 {
- t.Errorf("bitset: inconsistent value after SetBit 1, got %s want %s", z, z1)
- }
- z.SetBit(z, i, 0)
- altSetBit(z1, z1, i, 0)
- if z.Bit(i) != 0 {
- t.Errorf("bitset: bit %d of %s got 1 want 0", i, x)
- }
- if z.Cmp(z1) != 0 {
- t.Errorf("bitset: inconsistent value after SetBit 0, got %s want %s", z, z1)
- }
- altSetBit(z1, z1, i, old)
- z.SetBit(z, i, old)
- if z.Cmp(z1) != 0 {
- t.Errorf("bitset: inconsistent value after SetBit old, got %s want %s", z, z1)
- }
- }
- if z.Cmp(x) != 0 {
- t.Errorf("bitset: got %s want %s", z, x)
- }
-}
-
-var bitsetTests = []struct {
- x string
- i int
- b uint
-}{
- {"0", 0, 0},
- {"0", 200, 0},
- {"1", 0, 1},
- {"1", 1, 0},
- {"-1", 0, 1},
- {"-1", 200, 1},
- {"0x2000000000000000000000000000", 108, 0},
- {"0x2000000000000000000000000000", 109, 1},
- {"0x2000000000000000000000000000", 110, 0},
- {"-0x2000000000000000000000000001", 108, 1},
- {"-0x2000000000000000000000000001", 109, 0},
- {"-0x2000000000000000000000000001", 110, 1},
-}
-
-func TestBitSet(t *testing.T) {
- for _, test := range bitwiseTests {
- x := new(Int)
- x.SetString(test.x, 0)
- testBitset(t, x)
- x = new(Int)
- x.SetString(test.y, 0)
- testBitset(t, x)
- }
- for i, test := range bitsetTests {
- x := new(Int)
- x.SetString(test.x, 0)
- b := x.Bit(test.i)
- if b != test.b {
- t.Errorf("#%d got %v want %v", i, b, test.b)
- }
- }
- z := NewInt(1)
- z.SetBit(NewInt(0), 2, 1)
- if z.Cmp(NewInt(4)) != 0 {
- t.Errorf("destination leaked into result; got %s want 4", z)
- }
-}
-
-func BenchmarkBitset(b *testing.B) {
- z := new(Int)
- z.SetBit(z, 512, 1)
- b.ResetTimer()
- b.StartTimer()
- for i := b.N - 1; i >= 0; i-- {
- z.SetBit(z, i&512, 1)
- }
-}
-
-func BenchmarkBitsetNeg(b *testing.B) {
- z := NewInt(-1)
- z.SetBit(z, 512, 0)
- b.ResetTimer()
- b.StartTimer()
- for i := b.N - 1; i >= 0; i-- {
- z.SetBit(z, i&512, 0)
- }
-}
-
-func BenchmarkBitsetOrig(b *testing.B) {
- z := new(Int)
- altSetBit(z, z, 512, 1)
- b.ResetTimer()
- b.StartTimer()
- for i := b.N - 1; i >= 0; i-- {
- altSetBit(z, z, i&512, 1)
- }
-}
-
-func BenchmarkBitsetNegOrig(b *testing.B) {
- z := NewInt(-1)
- altSetBit(z, z, 512, 0)
- b.ResetTimer()
- b.StartTimer()
- for i := b.N - 1; i >= 0; i-- {
- altSetBit(z, z, i&512, 0)
- }
-}
-
-// tri generates the trinomial 2**(n*2) - 2**n - 1, which is always 3 mod 4 and
-// 7 mod 8, so that 2 is always a quadratic residue.
-func tri(n uint) *Int {
- x := NewInt(1)
- x.Lsh(x, n)
- x2 := new(Int).Lsh(x, n)
- x2.Sub(x2, x)
- x2.Sub(x2, intOne)
- return x2
-}
-
-func BenchmarkModSqrt225_Tonelli(b *testing.B) {
- p := tri(225)
- x := NewInt(2)
- for i := 0; i < b.N; i++ {
- x.SetUint64(2)
- x.modSqrtTonelliShanks(x, p)
- }
-}
-
-func BenchmarkModSqrt224_3Mod4(b *testing.B) {
- p := tri(225)
- x := new(Int).SetUint64(2)
- for i := 0; i < b.N; i++ {
- x.SetUint64(2)
- x.modSqrt3Mod4Prime(x, p)
- }
-}
-
-func BenchmarkModSqrt5430_Tonelli(b *testing.B) {
- p := tri(5430)
- x := new(Int).SetUint64(2)
- for i := 0; i < b.N; i++ {
- x.SetUint64(2)
- x.modSqrtTonelliShanks(x, p)
- }
-}
-
-func BenchmarkModSqrt5430_3Mod4(b *testing.B) {
- p := tri(5430)
- x := new(Int).SetUint64(2)
- for i := 0; i < b.N; i++ {
- x.SetUint64(2)
- x.modSqrt3Mod4Prime(x, p)
- }
-}
-
-func TestBitwise(t *testing.T) {
- x := new(Int)
- y := new(Int)
- for _, test := range bitwiseTests {
- x.SetString(test.x, 0)
- y.SetString(test.y, 0)
-
- testBitFun(t, "and", (*Int).And, x, y, test.and)
- testBitFunSelf(t, "and", (*Int).And, x, y, test.and)
- testBitFun(t, "andNot", (*Int).AndNot, x, y, test.andNot)
- testBitFunSelf(t, "andNot", (*Int).AndNot, x, y, test.andNot)
- testBitFun(t, "or", (*Int).Or, x, y, test.or)
- testBitFunSelf(t, "or", (*Int).Or, x, y, test.or)
- testBitFun(t, "xor", (*Int).Xor, x, y, test.xor)
- testBitFunSelf(t, "xor", (*Int).Xor, x, y, test.xor)
- }
-}
-
-var notTests = []struct {
- in string
- out string
-}{
- {"0", "-1"},
- {"1", "-2"},
- {"7", "-8"},
- {"0", "-1"},
- {"-81910", "81909"},
- {
- "298472983472983471903246121093472394872319615612417471234712061",
- "-298472983472983471903246121093472394872319615612417471234712062",
- },
-}
-
-func TestNot(t *testing.T) {
- in := new(Int)
- out := new(Int)
- expected := new(Int)
- for i, test := range notTests {
- in.SetString(test.in, 10)
- expected.SetString(test.out, 10)
- out = out.Not(in)
- if out.Cmp(expected) != 0 {
- t.Errorf("#%d: got %s want %s", i, out, expected)
- }
- out = out.Not(out)
- if out.Cmp(in) != 0 {
- t.Errorf("#%d: got %s want %s", i, out, in)
- }
- }
-}
-
-var modInverseTests = []struct {
- element string
- modulus string
-}{
- {"1234567", "458948883992"},
- {"239487239847", "2410312426921032588552076022197566074856950548502459942654116941958108831682612228890093858261341614673227141477904012196503648957050582631942730706805009223062734745341073406696246014589361659774041027169249453200378729434170325843778659198143763193776859869524088940195577346119843545301547043747207749969763750084308926339295559968882457872412993810129130294592999947926365264059284647209730384947211681434464714438488520940127459844288859336526896320919633919"},
-}
-
-func TestModInverse(t *testing.T) {
- var element, modulus, gcd, inverse Int
- one := NewInt(1)
- for i, 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)
- }
- }
- // exhaustive test for small values
- for n := 2; n < 100; n++ {
- (&modulus).SetInt64(int64(n))
- for x := 1; x < n; x++ {
- (&element).SetInt64(int64(x))
- (&gcd).GCD(nil, nil, &element, &modulus)
- if (&gcd).Cmp(one) != 0 {
- continue
- }
- (&inverse).ModInverse(&element, &modulus)
- (&inverse).Mul(&inverse, &element)
- (&inverse).Mod(&inverse, &modulus)
- if (&inverse).Cmp(one) != 0 {
- t.Errorf("ModInverse(%d,%d)*%d%%%d=%d, not 1", &element, &modulus, &element, &modulus, &inverse)
- }
- }
- }
-}
-
-// 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 {
- var sqChk, sqrtChk, sqrtsq Int
- sq.Mul(elt, elt)
- sq.Mod(sq, mod)
- z := sqrt.ModSqrt(sq, mod)
- if z != sqrt {
- t.Errorf("ModSqrt returned wrong value %s", z)
- }
-
- // test ModSqrt arguments outside the range [0,mod)
- sqChk.Add(sq, mod)
- z = sqrtChk.ModSqrt(&sqChk, mod)
- if z != &sqrtChk || z.Cmp(sqrt) != 0 {
- t.Errorf("ModSqrt returned inconsistent value %s", z)
- }
- sqChk.Sub(sq, mod)
- z = sqrtChk.ModSqrt(&sqChk, mod)
- if z != &sqrtChk || z.Cmp(sqrt) != 0 {
- t.Errorf("ModSqrt returned inconsistent value %s", z)
- }
-
- // make sure we actually got a square root
- if sqrt.Cmp(elt) == 0 {
- return true // we found the "desired" square root
- }
- sqrtsq.Mul(sqrt, sqrt) // make sure we found the "other" one
- sqrtsq.Mod(&sqrtsq, mod)
- return sq.Cmp(&sqrtsq) == 0
-}
-
-func TestModSqrt(t *testing.T) {
- var elt, mod, modx4, sq, sqrt Int
- r := rand.New(rand.NewSource(9))
- for i, s := range primes[1:] { // skip 2, use only odd primes
- mod.SetString(s, 10)
- modx4.Lsh(&mod, 2)
-
- // test a few random elements per prime
- for x := 1; x < 5; x++ {
- elt.Rand(r, &modx4)
- elt.Sub(&elt, &mod) // test range [-mod, 3*mod)
- if !testModSqrt(t, &elt, &mod, &sq, &sqrt) {
- t.Errorf("#%d: failed (sqrt(e) = %s)", i, &sqrt)
- }
- }
-
- if testing.Short() && i > 2 {
- break
- }
- }
-
- if testing.Short() {
- return
- }
-
- // exhaustive test for small values
- for n := 3; n < 100; n++ {
- mod.SetInt64(int64(n))
- if !mod.ProbablyPrime(10) {
- continue
- }
- isSquare := make([]bool, n)
-
- // test all the squares
- for x := 1; x < n; x++ {
- elt.SetInt64(int64(x))
- if !testModSqrt(t, &elt, &mod, &sq, &sqrt) {
- t.Errorf("#%d: failed (sqrt(%d,%d) = %s)", x, &elt, &mod, &sqrt)
- }
- isSquare[sq.Uint64()] = true
- }
-
- // test all non-squares
- for x := 1; x < n; x++ {
- sq.SetInt64(int64(x))
- z := sqrt.ModSqrt(&sq, &mod)
- if !isSquare[x] && z != nil {
- t.Errorf("#%d: failed (sqrt(%d,%d) = nil)", x, &sqrt, &mod)
- }
- }
- }
-}
-
-func TestJacobi(t *testing.T) {
- testCases := []struct {
- x, y int64
- result int
- }{
- {0, 1, 1},
- {0, -1, 1},
- {1, 1, 1},
- {1, -1, 1},
- {0, 5, 0},
- {1, 5, 1},
- {2, 5, -1},
- {-2, 5, -1},
- {2, -5, -1},
- {-2, -5, 1},
- {3, 5, -1},
- {5, 5, 0},
- {-5, 5, 0},
- {6, 5, 1},
- {6, -5, 1},
- {-6, 5, 1},
- {-6, -5, -1},
- }
-
- var x, y Int
-
- for i, test := range testCases {
- x.SetInt64(test.x)
- y.SetInt64(test.y)
- expected := test.result
- actual := Jacobi(&x, &y)
- if actual != expected {
- t.Errorf("#%d: Jacobi(%d, %d) = %d, but expected %d", i, test.x, test.y, actual, expected)
- }
- }
-}
-
-func TestJacobiPanic(t *testing.T) {
- const failureMsg = "test failure"
- defer func() {
- msg := recover()
- if msg == nil || msg == failureMsg {
- panic(msg)
- }
- t.Log(msg)
- }()
- x := NewInt(1)
- y := NewInt(2)
- // Jacobi should panic when the second argument is even.
- Jacobi(x, y)
- panic(failureMsg)
-}
-
-func TestIssue2607(t *testing.T) {
- // This code sequence used to hang.
- n := NewInt(10)
- n.Rand(rand.New(rand.NewSource(9)), n)
-}
diff --git a/src/cmd/compile/internal/big/intconv.go b/src/cmd/compile/internal/big/intconv.go
deleted file mode 100644
index daf674a..0000000
--- a/src/cmd/compile/internal/big/intconv.go
+++ /dev/null
@@ -1,248 +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.
-
-// This file implements int-to-string conversion functions.
-
-package big
-
-import (
- "errors"
- "fmt"
- "io"
-)
-
-// TODO(gri) Should rename itoa to utoa (there's no sign). That
-// would permit the introduction of itoa which is like utoa but
-// reserves a byte for a possible sign that's passed in. That
-// would permit Int.Text to be implemented w/o the need for
-// string copy if the number is negative.
-
-// Text returns the string representation of x in the given base.
-// Base must be between 2 and 36, inclusive. The result uses the
-// lower-case letters 'a' to 'z' for digit values >= 10. No base
-// prefix (such as "0x") is added to the string.
-func (x *Int) Text(base int) string {
- if x == nil {
- return "<nil>"
- }
- return string(x.abs.itoa(x.neg, base))
-}
-
-// Append appends the string representation of x, as generated by
-// x.Text(base), to buf and returns the extended buffer.
-func (x *Int) Append(buf []byte, base int) []byte {
- if x == nil {
- return append(buf, "<nil>"...)
- }
- return append(buf, x.abs.itoa(x.neg, base)...)
-}
-
-func (x *Int) String() string {
- return x.Text(10)
-}
-
-// write count copies of text to s
-func writeMultiple(s fmt.State, text string, count int) {
- if len(text) > 0 {
- b := []byte(text)
- for ; count > 0; count-- {
- s.Write(b)
- }
- }
-}
-
-// Format implements fmt.Formatter. It accepts the formats
-// 'b' (binary), 'o' (octal), 'd' (decimal), 'x' (lowercase
-// hexadecimal), and 'X' (uppercase hexadecimal).
-// Also supported are the full suite of package fmt's format
-// flags for integral types, including '+' and ' ' for sign
-// control, '#' for leading zero in octal and for hexadecimal,
-// a leading "0x" or "0X" for "%#x" and "%#X" respectively,
-// specification of minimum digits precision, output field
-// width, space or zero padding, and '-' for left or right
-// justification.
-//
-func (x *Int) Format(s fmt.State, ch rune) {
- // determine base
- var base int
- switch ch {
- case 'b':
- base = 2
- case 'o':
- base = 8
- case 'd', 's', 'v':
- base = 10
- case 'x', 'X':
- base = 16
- default:
- // unknown format
- fmt.Fprintf(s, "%%!%c(big.Int=%s)", ch, x.String())
- return
- }
-
- if x == nil {
- fmt.Fprint(s, "<nil>")
- return
- }
-
- // determine sign character
- sign := ""
- switch {
- case x.neg:
- sign = "-"
- case s.Flag('+'): // supersedes ' ' when both specified
- sign = "+"
- case s.Flag(' '):
- sign = " "
- }
-
- // determine prefix characters for indicating output base
- prefix := ""
- if s.Flag('#') {
- switch ch {
- case 'o': // octal
- prefix = "0"
- case 'x': // hexadecimal
- prefix = "0x"
- case 'X':
- prefix = "0X"
- }
- }
-
- digits := x.abs.utoa(base)
- if ch == 'X' {
- // faster than bytes.ToUpper
- for i, d := range digits {
- if 'a' <= d && d <= 'z' {
- digits[i] = 'A' + (d - 'a')
- }
- }
- }
-
- // number of characters for the three classes of number padding
- var left int // space characters to left of digits for right justification ("%8d")
- var zeros int // zero characters (actually cs[0]) as left-most digits ("%.8d")
- var right int // space characters to right of digits for left justification ("%-8d")
-
- // determine number padding from precision: the least number of digits to output
- precision, precisionSet := s.Precision()
- if precisionSet {
- switch {
- case len(digits) < precision:
- zeros = precision - len(digits) // count of zero padding
- case len(digits) == 1 && digits[0] == '0' && precision == 0:
- return // print nothing if zero value (x == 0) and zero precision ("." or ".0")
- }
- }
-
- // determine field pad from width: the least number of characters to output
- length := len(sign) + len(prefix) + zeros + len(digits)
- if width, widthSet := s.Width(); widthSet && length < width { // pad as specified
- switch d := width - length; {
- case s.Flag('-'):
- // pad on the right with spaces; supersedes '0' when both specified
- right = d
- case s.Flag('0') && !precisionSet:
- // pad with zeros unless precision also specified
- zeros = d
- default:
- // pad on the left with spaces
- left = d
- }
- }
-
- // print number as [left pad][sign][prefix][zero pad][digits][right pad]
- writeMultiple(s, " ", left)
- writeMultiple(s, sign, 1)
- writeMultiple(s, prefix, 1)
- writeMultiple(s, "0", zeros)
- s.Write(digits)
- writeMultiple(s, " ", right)
-}
-
-// scan sets z to the integer value corresponding to the longest possible prefix
-// read from r representing a signed integer number in a given conversion base.
-// It returns z, the actual conversion base used, and an error, if any. In the
-// error case, the value of z is undefined but the returned value is nil. The
-// syntax follows the syntax of integer literals in Go.
-//
-// The base argument must be 0 or a value from 2 through MaxBase. If the base
-// is 0, the string prefix determines the actual conversion base. A prefix of
-// ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a
-// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
-//
-func (z *Int) scan(r io.ByteScanner, base int) (*Int, int, error) {
- // determine sign
- neg, err := scanSign(r)
- if err != nil {
- return nil, 0, err
- }
-
- // determine mantissa
- z.abs, base, _, err = z.abs.scan(r, base, false)
- if err != nil {
- return nil, base, err
- }
- z.neg = len(z.abs) > 0 && neg // 0 has no sign
-
- return z, base, nil
-}
-
-func scanSign(r io.ByteScanner) (neg bool, err error) {
- var ch byte
- if ch, err = r.ReadByte(); err != nil {
- return false, err
- }
- switch ch {
- case '-':
- neg = true
- case '+':
- // nothing to do
- default:
- r.UnreadByte()
- }
- return
-}
-
-// byteReader is a local wrapper around fmt.ScanState;
-// it implements the ByteReader interface.
-type byteReader struct {
- fmt.ScanState
-}
-
-func (r byteReader) ReadByte() (byte, error) {
- ch, size, err := r.ReadRune()
- if size != 1 && err == nil {
- err = fmt.Errorf("invalid rune %#U", ch)
- }
- return byte(ch), err
-}
-
-func (r byteReader) UnreadByte() error {
- return r.UnreadRune()
-}
-
-// Scan is a support routine for fmt.Scanner; it sets z to the value of
-// the scanned number. It accepts the formats 'b' (binary), 'o' (octal),
-// 'd' (decimal), 'x' (lowercase hexadecimal), and 'X' (uppercase hexadecimal).
-func (z *Int) Scan(s fmt.ScanState, ch rune) error {
- s.SkipSpace() // skip leading space characters
- base := 0
- switch ch {
- case 'b':
- base = 2
- case 'o':
- base = 8
- case 'd':
- base = 10
- case 'x', 'X':
- base = 16
- case 's', 'v':
- // let scan determine the base
- default:
- return errors.New("Int.Scan: invalid verb")
- }
- _, _, err := z.scan(byteReader{s}, base)
- return err
-}
diff --git a/src/cmd/compile/internal/big/intconv_test.go b/src/cmd/compile/internal/big/intconv_test.go
deleted file mode 100644
index 5142081..0000000
--- a/src/cmd/compile/internal/big/intconv_test.go
+++ /dev/null
@@ -1,391 +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.
-
-package big
-
-import (
- "bytes"
- "fmt"
- "testing"
-)
-
-var stringTests = []struct {
- in string
- out string
- base int
- val int64
- ok bool
-}{
- {in: ""},
- {in: "a"},
- {in: "z"},
- {in: "+"},
- {in: "-"},
- {in: "0b"},
- {in: "0x"},
- {in: "2", base: 2},
- {in: "0b2", base: 0},
- {in: "08"},
- {in: "8", base: 8},
- {in: "0xg", base: 0},
- {in: "g", base: 16},
- {"0", "0", 0, 0, true},
- {"0", "0", 10, 0, true},
- {"0", "0", 16, 0, true},
- {"+0", "0", 0, 0, true},
- {"-0", "0", 0, 0, true},
- {"10", "10", 0, 10, true},
- {"10", "10", 10, 10, true},
- {"10", "10", 16, 16, true},
- {"-10", "-10", 16, -16, true},
- {"+10", "10", 16, 16, true},
- {"0x10", "16", 0, 16, true},
- {in: "0x10", base: 16},
- {"-0x10", "-16", 0, -16, true},
- {"+0x10", "16", 0, 16, true},
- {"00", "0", 0, 0, true},
- {"0", "0", 8, 0, true},
- {"07", "7", 0, 7, true},
- {"7", "7", 8, 7, true},
- {"023", "19", 0, 19, true},
- {"23", "23", 8, 19, true},
- {"cafebabe", "cafebabe", 16, 0xcafebabe, true},
- {"0b0", "0", 0, 0, true},
- {"-111", "-111", 2, -7, true},
- {"-0b111", "-7", 0, -7, true},
- {"0b1001010111", "599", 0, 0x257, true},
- {"1001010111", "1001010111", 2, 0x257, true},
-}
-
-func TestIntText(t *testing.T) {
- z := new(Int)
- for _, test := range stringTests {
- if !test.ok {
- continue
- }
-
- _, ok := z.SetString(test.in, test.base)
- if !ok {
- t.Errorf("%v: failed to parse", test)
- continue
- }
-
- base := test.base
- if base == 0 {
- base = 10
- }
-
- if got := z.Text(base); got != test.out {
- t.Errorf("%v: got %s; want %s", test, got, test.out)
- }
- }
-}
-
-func TestAppendText(t *testing.T) {
- z := new(Int)
- var buf []byte
- for _, test := range stringTests {
- if !test.ok {
- continue
- }
-
- _, ok := z.SetString(test.in, test.base)
- if !ok {
- t.Errorf("%v: failed to parse", test)
- continue
- }
-
- base := test.base
- if base == 0 {
- base = 10
- }
-
- i := len(buf)
- buf = z.Append(buf, base)
- if got := string(buf[i:]); got != test.out {
- t.Errorf("%v: got %s; want %s", test, got, test.out)
- }
- }
-}
-
-func format(base int) string {
- switch base {
- case 2:
- return "%b"
- case 8:
- return "%o"
- case 16:
- return "%x"
- }
- return "%d"
-}
-
-func TestGetString(t *testing.T) {
- z := new(Int)
- for i, test := range stringTests {
- if !test.ok {
- continue
- }
- z.SetInt64(test.val)
-
- if test.base == 10 {
- if got := z.String(); got != test.out {
- t.Errorf("#%da got %s; want %s", i, got, test.out)
- }
- }
-
- if got := fmt.Sprintf(format(test.base), z); got != test.out {
- t.Errorf("#%db got %s; want %s", i, got, test.out)
- }
- }
-}
-
-func TestSetString(t *testing.T) {
- tmp := new(Int)
- for i, test := range stringTests {
- // initialize to a non-zero value so that issues with parsing
- // 0 are detected
- tmp.SetInt64(1234567890)
- n1, ok1 := new(Int).SetString(test.in, test.base)
- n2, ok2 := tmp.SetString(test.in, test.base)
- expected := NewInt(test.val)
- if ok1 != test.ok || ok2 != test.ok {
- t.Errorf("#%d (input '%s') ok incorrect (should be %t)", i, test.in, test.ok)
- continue
- }
- if !ok1 {
- if n1 != nil {
- t.Errorf("#%d (input '%s') n1 != nil", i, test.in)
- }
- continue
- }
- if !ok2 {
- if n2 != nil {
- t.Errorf("#%d (input '%s') n2 != nil", i, test.in)
- }
- continue
- }
-
- if ok1 && !isNormalized(n1) {
- t.Errorf("#%d (input '%s'): %v is not normalized", i, test.in, *n1)
- }
- if ok2 && !isNormalized(n2) {
- t.Errorf("#%d (input '%s'): %v is not normalized", i, test.in, *n2)
- }
-
- if n1.Cmp(expected) != 0 {
- t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n1, test.val)
- }
- if n2.Cmp(expected) != 0 {
- t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n2, test.val)
- }
- }
-}
-
-var formatTests = []struct {
- input string
- format string
- output string
-}{
- {"<nil>", "%x", "<nil>"},
- {"<nil>", "%#x", "<nil>"},
- {"<nil>", "%#y", "%!y(big.Int=<nil>)"},
-
- {"10", "%b", "1010"},
- {"10", "%o", "12"},
- {"10", "%d", "10"},
- {"10", "%v", "10"},
- {"10", "%x", "a"},
- {"10", "%X", "A"},
- {"-10", "%X", "-A"},
- {"10", "%y", "%!y(big.Int=10)"},
- {"-10", "%y", "%!y(big.Int=-10)"},
-
- {"10", "%#b", "1010"},
- {"10", "%#o", "012"},
- {"10", "%#d", "10"},
- {"10", "%#v", "10"},
- {"10", "%#x", "0xa"},
- {"10", "%#X", "0XA"},
- {"-10", "%#X", "-0XA"},
- {"10", "%#y", "%!y(big.Int=10)"},
- {"-10", "%#y", "%!y(big.Int=-10)"},
-
- {"1234", "%d", "1234"},
- {"1234", "%3d", "1234"},
- {"1234", "%4d", "1234"},
- {"-1234", "%d", "-1234"},
- {"1234", "% 5d", " 1234"},
- {"1234", "%+5d", "+1234"},
- {"1234", "%-5d", "1234 "},
- {"1234", "%x", "4d2"},
- {"1234", "%X", "4D2"},
- {"-1234", "%3x", "-4d2"},
- {"-1234", "%4x", "-4d2"},
- {"-1234", "%5x", " -4d2"},
- {"-1234", "%-5x", "-4d2 "},
- {"1234", "%03d", "1234"},
- {"1234", "%04d", "1234"},
- {"1234", "%05d", "01234"},
- {"1234", "%06d", "001234"},
- {"-1234", "%06d", "-01234"},
- {"1234", "%+06d", "+01234"},
- {"1234", "% 06d", " 01234"},
- {"1234", "%-6d", "1234 "},
- {"1234", "%-06d", "1234 "},
- {"-1234", "%-06d", "-1234 "},
-
- {"1234", "%.3d", "1234"},
- {"1234", "%.4d", "1234"},
- {"1234", "%.5d", "01234"},
- {"1234", "%.6d", "001234"},
- {"-1234", "%.3d", "-1234"},
- {"-1234", "%.4d", "-1234"},
- {"-1234", "%.5d", "-01234"},
- {"-1234", "%.6d", "-001234"},
-
- {"1234", "%8.3d", " 1234"},
- {"1234", "%8.4d", " 1234"},
- {"1234", "%8.5d", " 01234"},
- {"1234", "%8.6d", " 001234"},
- {"-1234", "%8.3d", " -1234"},
- {"-1234", "%8.4d", " -1234"},
- {"-1234", "%8.5d", " -01234"},
- {"-1234", "%8.6d", " -001234"},
-
- {"1234", "%+8.3d", " +1234"},
- {"1234", "%+8.4d", " +1234"},
- {"1234", "%+8.5d", " +01234"},
- {"1234", "%+8.6d", " +001234"},
- {"-1234", "%+8.3d", " -1234"},
- {"-1234", "%+8.4d", " -1234"},
- {"-1234", "%+8.5d", " -01234"},
- {"-1234", "%+8.6d", " -001234"},
-
- {"1234", "% 8.3d", " 1234"},
- {"1234", "% 8.4d", " 1234"},
- {"1234", "% 8.5d", " 01234"},
- {"1234", "% 8.6d", " 001234"},
- {"-1234", "% 8.3d", " -1234"},
- {"-1234", "% 8.4d", " -1234"},
- {"-1234", "% 8.5d", " -01234"},
- {"-1234", "% 8.6d", " -001234"},
-
- {"1234", "%.3x", "4d2"},
- {"1234", "%.4x", "04d2"},
- {"1234", "%.5x", "004d2"},
- {"1234", "%.6x", "0004d2"},
- {"-1234", "%.3x", "-4d2"},
- {"-1234", "%.4x", "-04d2"},
- {"-1234", "%.5x", "-004d2"},
- {"-1234", "%.6x", "-0004d2"},
-
- {"1234", "%8.3x", " 4d2"},
- {"1234", "%8.4x", " 04d2"},
- {"1234", "%8.5x", " 004d2"},
- {"1234", "%8.6x", " 0004d2"},
- {"-1234", "%8.3x", " -4d2"},
- {"-1234", "%8.4x", " -04d2"},
- {"-1234", "%8.5x", " -004d2"},
- {"-1234", "%8.6x", " -0004d2"},
-
- {"1234", "%+8.3x", " +4d2"},
- {"1234", "%+8.4x", " +04d2"},
- {"1234", "%+8.5x", " +004d2"},
- {"1234", "%+8.6x", " +0004d2"},
- {"-1234", "%+8.3x", " -4d2"},
- {"-1234", "%+8.4x", " -04d2"},
- {"-1234", "%+8.5x", " -004d2"},
- {"-1234", "%+8.6x", " -0004d2"},
-
- {"1234", "% 8.3x", " 4d2"},
- {"1234", "% 8.4x", " 04d2"},
- {"1234", "% 8.5x", " 004d2"},
- {"1234", "% 8.6x", " 0004d2"},
- {"1234", "% 8.7x", " 00004d2"},
- {"1234", "% 8.8x", " 000004d2"},
- {"-1234", "% 8.3x", " -4d2"},
- {"-1234", "% 8.4x", " -04d2"},
- {"-1234", "% 8.5x", " -004d2"},
- {"-1234", "% 8.6x", " -0004d2"},
- {"-1234", "% 8.7x", "-00004d2"},
- {"-1234", "% 8.8x", "-000004d2"},
-
- {"1234", "%-8.3d", "1234 "},
- {"1234", "%-8.4d", "1234 "},
- {"1234", "%-8.5d", "01234 "},
- {"1234", "%-8.6d", "001234 "},
- {"1234", "%-8.7d", "0001234 "},
- {"1234", "%-8.8d", "00001234"},
- {"-1234", "%-8.3d", "-1234 "},
- {"-1234", "%-8.4d", "-1234 "},
- {"-1234", "%-8.5d", "-01234 "},
- {"-1234", "%-8.6d", "-001234 "},
- {"-1234", "%-8.7d", "-0001234"},
- {"-1234", "%-8.8d", "-00001234"},
-
- {"16777215", "%b", "111111111111111111111111"}, // 2**24 - 1
-
- {"0", "%.d", ""},
- {"0", "%.0d", ""},
- {"0", "%3.d", ""},
-}
-
-func TestFormat(t *testing.T) {
- for i, test := range formatTests {
- var x *Int
- if test.input != "<nil>" {
- var ok bool
- x, ok = new(Int).SetString(test.input, 0)
- if !ok {
- t.Errorf("#%d failed reading input %s", i, test.input)
- }
- }
- output := fmt.Sprintf(test.format, x)
- if output != test.output {
- t.Errorf("#%d got %q; want %q, {%q, %q, %q}", i, output, test.output, test.input, test.format, test.output)
- }
- }
-}
-
-var scanTests = []struct {
- input string
- format string
- output string
- remaining int
-}{
- {"1010", "%b", "10", 0},
- {"0b1010", "%v", "10", 0},
- {"12", "%o", "10", 0},
- {"012", "%v", "10", 0},
- {"10", "%d", "10", 0},
- {"10", "%v", "10", 0},
- {"a", "%x", "10", 0},
- {"0xa", "%v", "10", 0},
- {"A", "%X", "10", 0},
- {"-A", "%X", "-10", 0},
- {"+0b1011001", "%v", "89", 0},
- {"0xA", "%v", "10", 0},
- {"0 ", "%v", "0", 1},
- {"2+3", "%v", "2", 2},
- {"0XABC 12", "%v", "2748", 3},
-}
-
-func TestScan(t *testing.T) {
- var buf bytes.Buffer
- for i, test := range scanTests {
- x := new(Int)
- buf.Reset()
- buf.WriteString(test.input)
- if _, err := fmt.Fscanf(&buf, test.format, x); err != nil {
- t.Errorf("#%d error: %s", i, err)
- }
- if x.String() != test.output {
- t.Errorf("#%d got %s; want %s", i, x.String(), test.output)
- }
- if buf.Len() != test.remaining {
- t.Errorf("#%d got %d bytes remaining; want %d", i, buf.Len(), test.remaining)
- }
- }
-}
diff --git a/src/cmd/compile/internal/big/intmarsh.go b/src/cmd/compile/internal/big/intmarsh.go
deleted file mode 100644
index 34bc73e..0000000
--- a/src/cmd/compile/internal/big/intmarsh.go
+++ /dev/null
@@ -1,78 +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.
-
-// This file implements encoding/decoding of Ints.
-
-package big
-
-import "fmt"
-
-// Gob codec version. Permits backward-compatible changes to the encoding.
-const intGobVersion byte = 1
-
-// GobEncode implements the gob.GobEncoder interface.
-func (x *Int) GobEncode() ([]byte, error) {
- if x == nil {
- return nil, nil
- }
- buf := make([]byte, 1+len(x.abs)*_S) // extra byte for version and sign bit
- i := x.abs.bytes(buf) - 1 // i >= 0
- b := intGobVersion << 1 // make space for sign bit
- if x.neg {
- b |= 1
- }
- buf[i] = b
- return buf[i:], nil
-}
-
-// GobDecode implements the gob.GobDecoder interface.
-func (z *Int) GobDecode(buf []byte) error {
- if len(buf) == 0 {
- // Other side sent a nil or default value.
- *z = Int{}
- return nil
- }
- b := buf[0]
- if b>>1 != intGobVersion {
- return fmt.Errorf("Int.GobDecode: encoding version %d not supported", b>>1)
- }
- z.neg = b&1 != 0
- z.abs = z.abs.setBytes(buf[1:])
- return nil
-}
-
-// MarshalText implements the encoding.TextMarshaler interface.
-func (x *Int) MarshalText() (text []byte, err error) {
- if x == nil {
- return []byte("<nil>"), nil
- }
- return x.abs.itoa(x.neg, 10), nil
-}
-
-// UnmarshalText implements the encoding.TextUnmarshaler interface.
-func (z *Int) UnmarshalText(text []byte) error {
- // TODO(gri): get rid of the []byte/string conversion
- if _, ok := z.SetString(string(text), 0); !ok {
- return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text)
- }
- return nil
-}
-
-// The JSON marshallers are only here for API backward compatibility
-// (programs that explicitly look for these two methods). JSON works
-// fine with the TextMarshaler only.
-
-// MarshalJSON implements the json.Marshaler interface.
-func (x *Int) MarshalJSON() ([]byte, error) {
- return x.MarshalText()
-}
-
-// UnmarshalJSON implements the json.Unmarshaler interface.
-func (z *Int) UnmarshalJSON(text []byte) error {
- // Ignore null, like in the main JSON package.
- if string(text) == "null" {
- return nil
- }
- return z.UnmarshalText(text)
-}
diff --git a/src/cmd/compile/internal/big/intmarsh_test.go b/src/cmd/compile/internal/big/intmarsh_test.go
deleted file mode 100644
index f82956c..0000000
--- a/src/cmd/compile/internal/big/intmarsh_test.go
+++ /dev/null
@@ -1,121 +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.
-
-package big
-
-import (
- "bytes"
- "encoding/gob"
- "encoding/json"
- "encoding/xml"
- "testing"
-)
-
-var encodingTests = []string{
- "0",
- "1",
- "2",
- "10",
- "1000",
- "1234567890",
- "298472983472983471903246121093472394872319615612417471234712061",
-}
-
-func TestIntGobEncoding(t *testing.T) {
- var medium bytes.Buffer
- enc := gob.NewEncoder(&medium)
- dec := gob.NewDecoder(&medium)
- for _, test := range encodingTests {
- for _, sign := range []string{"", "+", "-"} {
- x := sign + test
- medium.Reset() // empty buffer for each test case (in case of failures)
- var tx Int
- tx.SetString(x, 10)
- if err := enc.Encode(&tx); err != nil {
- t.Errorf("encoding of %s failed: %s", &tx, err)
- continue
- }
- var rx Int
- if err := dec.Decode(&rx); err != nil {
- t.Errorf("decoding of %s failed: %s", &tx, err)
- continue
- }
- if rx.Cmp(&tx) != 0 {
- t.Errorf("transmission of %s failed: got %s want %s", &tx, &rx, &tx)
- }
- }
- }
-}
-
-// Sending a nil Int pointer (inside a slice) on a round trip through gob should yield a zero.
-// TODO: top-level nils.
-func TestGobEncodingNilIntInSlice(t *testing.T) {
- buf := new(bytes.Buffer)
- enc := gob.NewEncoder(buf)
- dec := gob.NewDecoder(buf)
-
- var in = make([]*Int, 1)
- err := enc.Encode(&in)
- if err != nil {
- t.Errorf("gob encode failed: %q", err)
- }
- var out []*Int
- err = dec.Decode(&out)
- if err != nil {
- t.Fatalf("gob decode failed: %q", err)
- }
- if len(out) != 1 {
- t.Fatalf("wrong len; want 1 got %d", len(out))
- }
- var zero Int
- if out[0].Cmp(&zero) != 0 {
- t.Fatalf("transmission of (*Int)(nil) failed: got %s want 0", out)
- }
-}
-
-func TestIntJSONEncoding(t *testing.T) {
- for _, test := range encodingTests {
- for _, sign := range []string{"", "+", "-"} {
- x := sign + test
- var tx Int
- tx.SetString(x, 10)
- b, err := json.Marshal(&tx)
- if err != nil {
- t.Errorf("marshaling of %s failed: %s", &tx, err)
- continue
- }
- var rx Int
- if err := json.Unmarshal(b, &rx); err != nil {
- t.Errorf("unmarshaling of %s failed: %s", &tx, err)
- continue
- }
- if rx.Cmp(&tx) != 0 {
- t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx)
- }
- }
- }
-}
-
-func TestIntXMLEncoding(t *testing.T) {
- for _, test := range encodingTests {
- for _, sign := range []string{"", "+", "-"} {
- x := sign + test
- var tx Int
- tx.SetString(x, 0)
- b, err := xml.Marshal(&tx)
- if err != nil {
- t.Errorf("marshaling of %s failed: %s", &tx, err)
- continue
- }
- var rx Int
- if err := xml.Unmarshal(b, &rx); err != nil {
- t.Errorf("unmarshaling of %s failed: %s", &tx, err)
- continue
- }
- if rx.Cmp(&tx) != 0 {
- t.Errorf("XML encoding of %s failed: got %s want %s", &tx, &rx, &tx)
- }
- }
- }
-}
diff --git a/src/cmd/compile/internal/big/nat.go b/src/cmd/compile/internal/big/nat.go
deleted file mode 100644
index 2e65d2a7..0000000
--- a/src/cmd/compile/internal/big/nat.go
+++ /dev/null
@@ -1,1305 +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.
-
-// 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.
-
-package big
-
-import (
- "math/rand"
- "sync"
-)
-
-// An unsigned integer x of the form
-//
-// x = x[n-1]*_B^(n-1) + x[n-2]*_B^(n-2) + ... + x[1]*_B + x[0]
-//
-// with 0 <= x[i] < _B and 0 <= i < n is stored in a slice of length n,
-// with the digits x[i] as the slice elements.
-//
-// A number is normalized if the slice contains no leading 0 digits.
-// During arithmetic operations, denormalized values may occur but are
-// always normalized before returning the final result. The normalized
-// representation of 0 is the empty or nil slice (length = 0).
-//
-type nat []Word
-
-var (
- natOne = nat{1}
- natTwo = nat{2}
- natTen = nat{10}
-)
-
-func (z nat) clear() {
- for i := range z {
- z[i] = 0
- }
-}
-
-func (z nat) norm() nat {
- i := len(z)
- for i > 0 && z[i-1] == 0 {
- i--
- }
- return z[0:i]
-}
-
-func (z nat) make(n int) nat {
- if n <= cap(z) {
- return z[:n] // reuse z
- }
- // Choosing a good value for e has significant performance impact
- // because it increases the chance that a value can be reused.
- const e = 4 // extra capacity
- return make(nat, n, n+e)
-}
-
-func (z nat) setWord(x Word) nat {
- if x == 0 {
- return z[:0]
- }
- z = z.make(1)
- z[0] = x
- return z
-}
-
-func (z nat) setUint64(x uint64) nat {
- // single-digit values
- if w := Word(x); uint64(w) == x {
- return z.setWord(w)
- }
-
- // compute number of words n required to represent x
- n := 0
- for t := x; t > 0; t >>= _W {
- n++
- }
-
- // split x into n words
- z = z.make(n)
- for i := range z {
- z[i] = Word(x & _M)
- x >>= _W
- }
-
- return z
-}
-
-func (z nat) set(x nat) nat {
- z = z.make(len(x))
- copy(z, x)
- return z
-}
-
-func (z nat) add(x, y nat) nat {
- m := len(x)
- n := len(y)
-
- switch {
- case m < n:
- return z.add(y, x)
- case m == 0:
- // n == 0 because m >= n; result is 0
- return z[:0]
- case n == 0:
- // result is x
- return z.set(x)
- }
- // m > 0
-
- z = z.make(m + 1)
- c := addVV(z[0:n], x, y)
- if m > n {
- c = addVW(z[n:m], x[n:], c)
- }
- z[m] = c
-
- return z.norm()
-}
-
-func (z nat) sub(x, y nat) nat {
- m := len(x)
- n := len(y)
-
- switch {
- case m < n:
- panic("underflow")
- case m == 0:
- // n == 0 because m >= n; result is 0
- return z[:0]
- case n == 0:
- // result is x
- return z.set(x)
- }
- // m > 0
-
- z = z.make(m)
- c := subVV(z[0:n], x, y)
- if m > n {
- c = subVW(z[n:], x[n:], c)
- }
- if c != 0 {
- panic("underflow")
- }
-
- return z.norm()
-}
-
-func (x nat) cmp(y nat) (r int) {
- m := len(x)
- n := len(y)
- if m != n || m == 0 {
- switch {
- case m < n:
- r = -1
- case m > n:
- r = 1
- }
- return
- }
-
- i := m - 1
- for i > 0 && x[i] == y[i] {
- i--
- }
-
- switch {
- case x[i] < y[i]:
- r = -1
- case x[i] > y[i]:
- r = 1
- }
- return
-}
-
-func (z nat) mulAddWW(x nat, y, r Word) nat {
- m := len(x)
- if m == 0 || y == 0 {
- return z.setWord(r) // result is r
- }
- // m > 0
-
- z = z.make(m + 1)
- z[m] = mulAddVWW(z[0:m], x, y, r)
-
- return z.norm()
-}
-
-// basicMul multiplies x and y and leaves the result in z.
-// The (non-normalized) result is placed in z[0 : len(x) + len(y)].
-func basicMul(z, x, y nat) {
- z[0 : len(x)+len(y)].clear() // initialize z
- for i, d := range y {
- if d != 0 {
- z[len(x)+i] = addMulVVW(z[i:i+len(x)], x, d)
- }
- }
-}
-
-// montgomery computes z mod m = x*y*2**(-n*_W) mod m,
-// assuming k = -1/m mod 2**_W.
-// z is used for storing the result which is returned;
-// z must not alias x, y or m.
-// See Gueron, "Efficient Software Implementations of Modular Exponentiation".
-// https://eprint.iacr.org/2011/239.pdf
-// In the terminology of that paper, this is an "Almost Montgomery Multiplication":
-// x and y are required to satisfy 0 <= z < 2**(n*_W) and then the result
-// z is guaranteed to satisfy 0 <= z < 2**(n*_W), but it may not be < m.
-func (z nat) montgomery(x, y, m nat, k Word, n int) nat {
- // This code assumes x, y, m are all the same length, n.
- // (required by addMulVVW and the for loop).
- // It also assumes that x, y are already reduced mod m,
- // or else the result will not be properly reduced.
- if len(x) != n || len(y) != n || len(m) != n {
- panic("math/big: mismatched montgomery number lengths")
- }
- z = z.make(n)
- 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:])
- cx := c + c2
- cy := cx + c3
- z[n-1] = cy
- if cx < c2 || cy < c3 {
- c = 1
- } else {
- c = 0
- }
- }
- if c != 0 {
- subVV(z, z, m)
- }
- return z
-}
-
-// Fast version of z[0:n+n>>1].add(z[0:n+n>>1], x[0:n]) w/o bounds checks.
-// Factored out for readability - do not use outside karatsuba.
-func karatsubaAdd(z, x nat, n int) {
- if c := addVV(z[0:n], z, x); c != 0 {
- addVW(z[n:n+n>>1], z[n:], c)
- }
-}
-
-// Like karatsubaAdd, but does subtract.
-func karatsubaSub(z, x nat, n int) {
- if c := subVV(z[0:n], z, x); c != 0 {
- subVW(z[n:n+n>>1], z[n:], c)
- }
-}
-
-// Operands that are shorter than karatsubaThreshold are multiplied using
-// "grade school" multiplication; for longer operands the Karatsuba algorithm
-// is used.
-var karatsubaThreshold int = 40 // computed by calibrate.go
-
-// karatsuba multiplies x and y and leaves the result in z.
-// Both x and y must have the same length n and n must be a
-// power of 2. The result vector z must have len(z) >= 6*n.
-// The (non-normalized) result is placed in z[0 : 2*n].
-func karatsuba(z, x, y nat) {
- n := len(y)
-
- // Switch to basic multiplication if numbers are odd or small.
- // (n is always even if karatsubaThreshold is even, but be
- // conservative)
- if n&1 != 0 || n < karatsubaThreshold || n < 2 {
- basicMul(z, x, y)
- return
- }
- // n&1 == 0 && n >= karatsubaThreshold && n >= 2
-
- // Karatsuba multiplication is based on the observation that
- // for two numbers x and y with:
- //
- // x = x1*b + x0
- // y = y1*b + y0
- //
- // the product x*y can be obtained with 3 products z2, z1, z0
- // instead of 4:
- //
- // x*y = x1*y1*b*b + (x1*y0 + x0*y1)*b + x0*y0
- // = z2*b*b + z1*b + z0
- //
- // with:
- //
- // xd = x1 - x0
- // yd = y0 - y1
- //
- // z1 = xd*yd + z2 + z0
- // = (x1-x0)*(y0 - y1) + z2 + z0
- // = x1*y0 - x1*y1 - x0*y0 + x0*y1 + z2 + z0
- // = x1*y0 - z2 - z0 + x0*y1 + z2 + z0
- // = x1*y0 + x0*y1
-
- // split x, y into "digits"
- n2 := n >> 1 // n2 >= 1
- x1, x0 := x[n2:], x[0:n2] // x = x1*b + y0
- y1, y0 := y[n2:], y[0:n2] // y = y1*b + y0
-
- // z is used for the result and temporary storage:
- //
- // 6*n 5*n 4*n 3*n 2*n 1*n 0*n
- // z = [z2 copy|z0 copy| xd*yd | yd:xd | x1*y1 | x0*y0 ]
- //
- // For each recursive call of karatsuba, an unused slice of
- // z is passed in that has (at least) half the length of the
- // caller's z.
-
- // compute z0 and z2 with the result "in place" in z
- karatsuba(z, x0, y0) // z0 = x0*y0
- karatsuba(z[n:], x1, y1) // z2 = x1*y1
-
- // compute xd (or the negative value if underflow occurs)
- s := 1 // sign of product xd*yd
- xd := z[2*n : 2*n+n2]
- if subVV(xd, x1, x0) != 0 { // x1-x0
- s = -s
- subVV(xd, x0, x1) // x0-x1
- }
-
- // compute yd (or the negative value if underflow occurs)
- yd := z[2*n+n2 : 3*n]
- if subVV(yd, y0, y1) != 0 { // y0-y1
- s = -s
- subVV(yd, y1, y0) // y1-y0
- }
-
- // p = (x1-x0)*(y0-y1) == x1*y0 - x1*y1 - x0*y0 + x0*y1 for s > 0
- // p = (x0-x1)*(y0-y1) == x0*y0 - x0*y1 - x1*y0 + x1*y1 for s < 0
- p := z[n*3:]
- karatsuba(p, xd, yd)
-
- // save original z2:z0
- // (ok to use upper half of z since we're done recursing)
- r := z[n*4:]
- copy(r, z[:n*2])
-
- // add up all partial products
- //
- // 2*n n 0
- // z = [ z2 | z0 ]
- // + [ z0 ]
- // + [ z2 ]
- // + [ p ]
- //
- karatsubaAdd(z[n2:], r, n)
- karatsubaAdd(z[n2:], r[n:], n)
- if s > 0 {
- karatsubaAdd(z[n2:], p, n)
- } else {
- karatsubaSub(z[n2:], p, n)
- }
-}
-
-// alias reports whether x and y share the same base array.
-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]
-}
-
-// addAt implements z += x<<(_W*i); z must be long enough.
-// (we don't use nat.add because we need z to stay the same
-// slice, and we don't need to normalize z after each addition)
-func addAt(z, x nat, i int) {
- if n := len(x); n > 0 {
- if c := addVV(z[i:i+n], z[i:], x); c != 0 {
- j := i + n
- if j < len(z) {
- addVW(z[j:], z[j:], c)
- }
- }
- }
-}
-
-func max(x, y int) int {
- if x > y {
- return x
- }
- return y
-}
-
-// 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
-// result is the largest number that can be divided repeatedly by 2 before
-// becoming about the value of karatsubaThreshold.
-func karatsubaLen(n int) int {
- i := uint(0)
- for n > karatsubaThreshold {
- n >>= 1
- i++
- }
- return n << i
-}
-
-func (z nat) mul(x, y nat) nat {
- m := len(x)
- n := len(y)
-
- switch {
- case m < n:
- return z.mul(y, x)
- case m == 0 || n == 0:
- return z[:0]
- case n == 1:
- return z.mulAddWW(x, y[0], 0)
- }
- // m >= n > 1
-
- // determine if z can be reused
- if alias(z, x) || alias(z, y) {
- z = nil // z is an alias for x or y - cannot reuse
- }
-
- // use basic multiplication if the numbers are small
- if n < karatsubaThreshold {
- z = z.make(m + n)
- basicMul(z, x, y)
- return z.norm()
- }
- // m >= n && n >= karatsubaThreshold && n >= 2
-
- // determine Karatsuba length k such that
- //
- // x = xh*b + x0 (0 <= x0 < b)
- // y = yh*b + y0 (0 <= y0 < b)
- // b = 1<<(_W*k) ("base" of digits xi, yi)
- //
- k := karatsubaLen(n)
- // k <= n
-
- // multiply x0 and y0 via Karatsuba
- x0 := x[0:k] // x0 is not normalized
- y0 := y[0:k] // y0 is not normalized
- z = z.make(max(6*k, m+n)) // enough space for karatsuba of x0*y0 and full result of x*y
- karatsuba(z, x0, y0)
- z = z[0 : m+n] // z has final length but may be incomplete
- z[2*k:].clear() // upper portion of z is garbage (and 2*k <= m+n since k <= n <= m)
-
- // If xh != 0 or yh != 0, add the missing terms to z. For
- //
- // xh = xi*b^i + ... + x2*b^2 + x1*b (0 <= xi < b)
- // yh = y1*b (0 <= y1 < b)
- //
- // the missing terms are
- //
- // x0*y1*b and xi*y0*b^i, xi*y1*b^(i+1) for i > 0
- //
- // since all the yi for i > 1 are 0 by choice of k: If any of them
- // were > 0, then yh >= b^2 and thus y >= b^2. Then k' = k*2 would
- // be a larger valid threshold contradicting the assumption about k.
- //
- if k < n || m != n {
- var t nat
-
- // add x0*y1*b
- x0 := x0.norm()
- y1 := y[k:] // y1 is normalized because y is
- t = t.mul(x0, y1) // update t so we don't lose t's underlying array
- addAt(z, t, k)
-
- // add xi*y0<<i, xi*y1*b<<(i+k)
- y0 := y0.norm()
- for i := k; i < len(x); i += k {
- xi := x[i:]
- if len(xi) > k {
- xi = xi[:k]
- }
- xi = xi.norm()
- t = t.mul(xi, y0)
- addAt(z, t, i)
- t = t.mul(xi, y1)
- addAt(z, t, i+k)
- }
- }
-
- return z.norm()
-}
-
-// mulRange computes the product of all the unsigned integers in the
-// range [a, b] inclusively. If a > b (empty range), the result is 1.
-func (z nat) mulRange(a, b uint64) nat {
- switch {
- case a == 0:
- // cut long ranges short (optimization)
- return z.setUint64(0)
- case a > b:
- return z.setUint64(1)
- case a == b:
- return z.setUint64(a)
- case a+1 == b:
- return z.mul(nat(nil).setUint64(a), nat(nil).setUint64(b))
- }
- m := (a + b) / 2
- return z.mul(nat(nil).mulRange(a, m), nat(nil).mulRange(m+1, b))
-}
-
-// q = (x-r)/y, with 0 <= r < y
-func (z nat) divW(x nat, y Word) (q nat, r Word) {
- m := len(x)
- switch {
- case y == 0:
- panic("division by zero")
- case y == 1:
- q = z.set(x) // result is x
- return
- case m == 0:
- q = z[:0] // result is 0
- return
- }
- // m > 0
- z = z.make(m)
- r = divWVW(z, 0, x, y)
- q = z.norm()
- return
-}
-
-func (z nat) div(z2, u, v nat) (q, r nat) {
- if len(v) == 0 {
- panic("division by zero")
- }
-
- if u.cmp(v) < 0 {
- q = z[:0]
- r = z2.set(u)
- return
- }
-
- if len(v) == 1 {
- var r2 Word
- q, r2 = z.divW(u, v[0])
- r = z2.setWord(r2)
- return
- }
-
- q, r = z.divLarge(z2, u, v)
- return
-}
-
-// getNat returns a nat of len n. The contents may not be zero.
-func getNat(n int) nat {
- var z nat
- if v := natPool.Get(); v != nil {
- z = v.(nat)
- }
- return z.make(n)
-}
-
-func putNat(x nat) {
- natPool.Put(x)
-}
-
-var natPool sync.Pool
-
-// q = (uIn-r)/v, with 0 <= r < y
-// Uses z as storage for q, and u as storage for r if possible.
-// See Knuth, Volume 2, section 4.3.1, Algorithm D.
-// Preconditions:
-// len(v) >= 2
-// len(uIn) >= len(v)
-func (z nat) divLarge(u, uIn, v nat) (q, r nat) {
- n := len(v)
- m := len(uIn) - n
-
- // determine if z can be reused
- // TODO(gri) should find a better solution - this if statement
- // is very costly (see e.g. time pidigits -s -n 10000)
- if alias(z, uIn) || alias(z, v) {
- z = nil // z is an alias for uIn or v - cannot reuse
- }
- q = z.make(m + 1)
-
- qhatv := getNat(n + 1)
- if alias(u, uIn) || alias(u, v) {
- u = nil // u is an alias for uIn or v - cannot reuse
- }
- u = u.make(len(uIn) + 1)
- u.clear() // TODO(gri) no need to clear if we allocated a new u
-
- // D1.
- var v1 nat
- shift := nlz(v[n-1])
- if shift > 0 {
- // do not modify v, it may be used by another goroutine simultaneously
- v1 = getNat(n)
- shlVU(v1, v, shift)
- v = v1
- }
- u[len(uIn)] = shlVU(u[0:len(uIn)], uIn, shift)
-
- // D2.
- for j := m; j >= 0; j-- {
- // D3.
- qhat := Word(_M)
- if u[j+n] != v[n-1] {
- var rhat Word
- qhat, rhat = divWW(u[j+n], u[j+n-1], v[n-1])
-
- // x1 | x2 = q̂v_{n-2}
- x1, x2 := mulWW(qhat, v[n-2])
- // test if q̂v_{n-2} > br̂ + u_{j+n-2}
- for greaterThan(x1, x2, rhat, u[j+n-2]) {
- qhat--
- prevRhat := rhat
- rhat += v[n-1]
- // v[n-1] >= 0, so this tests for overflow.
- if rhat < prevRhat {
- break
- }
- x1, x2 = mulWW(qhat, v[n-2])
- }
- }
-
- // D4.
- qhatv[n] = mulAddVWW(qhatv[0:n], v, qhat, 0)
-
- c := subVV(u[j:j+len(qhatv)], u[j:], qhatv)
- if c != 0 {
- c := addVV(u[j:j+n], u[j:], v)
- u[j+n] += c
- qhat--
- }
-
- q[j] = qhat
- }
- if v1 != nil {
- putNat(v1)
- }
- putNat(qhatv)
-
- q = q.norm()
- shrVU(u, u, shift)
- r = u.norm()
-
- return q, r
-}
-
-// Length of x in bits. x must be normalized.
-func (x nat) bitLen() int {
- if i := len(x) - 1; i >= 0 {
- return i*_W + bitLen(x[i])
- }
- return 0
-}
-
-const deBruijn32 = 0x077CB531
-
-var deBruijn32Lookup = []byte{
- 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
- 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9,
-}
-
-const deBruijn64 = 0x03f79d71b4ca8b09
-
-var deBruijn64Lookup = []byte{
- 0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,
- 62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,
- 63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,
- 54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,
-}
-
-// trailingZeroBits returns the number of consecutive least significant zero
-// bits of x.
-func trailingZeroBits(x Word) uint {
- // x & -x leaves only the right-most bit set in the word. Let k be the
- // index of that bit. Since only a single bit is set, the value is two
- // to the power of k. Multiplying by a power of two is equivalent to
- // left shifting, in this case by k bits. The de Bruijn constant is
- // such that all six bit, consecutive substrings are distinct.
- // Therefore, if we have a left shifted version of this constant we can
- // find by how many bits it was shifted by looking at which six bit
- // substring ended up at the top of the word.
- // (Knuth, volume 4, section 7.3.1)
- switch _W {
- case 32:
- return uint(deBruijn32Lookup[((x&-x)*deBruijn32)>>27])
- case 64:
- return uint(deBruijn64Lookup[((x&-x)*(deBruijn64&_M))>>58])
- default:
- panic("unknown word size")
- }
-}
-
-// trailingZeroBits returns the number of consecutive least significant zero
-// bits of x.
-func (x nat) trailingZeroBits() uint {
- if len(x) == 0 {
- return 0
- }
- var i uint
- for x[i] == 0 {
- i++
- }
- // x[i] != 0
- return i*_W + trailingZeroBits(x[i])
-}
-
-// z = x << s
-func (z nat) shl(x nat, s uint) nat {
- m := len(x)
- if m == 0 {
- return z[:0]
- }
- // m > 0
-
- n := m + int(s/_W)
- z = z.make(n + 1)
- z[n] = shlVU(z[n-m:n], x, s%_W)
- z[0 : n-m].clear()
-
- return z.norm()
-}
-
-// z = x >> s
-func (z nat) shr(x nat, s uint) nat {
- m := len(x)
- n := m - int(s/_W)
- if n <= 0 {
- return z[:0]
- }
- // n > 0
-
- z = z.make(n)
- shrVU(z, x[m-n:], s%_W)
-
- return z.norm()
-}
-
-func (z nat) setBit(x nat, i uint, b uint) nat {
- j := int(i / _W)
- m := Word(1) << (i % _W)
- n := len(x)
- switch b {
- case 0:
- z = z.make(n)
- copy(z, x)
- if j >= n {
- // no need to grow
- return z
- }
- z[j] &^= m
- return z.norm()
- case 1:
- if j >= n {
- z = z.make(j + 1)
- z[n:].clear()
- } else {
- z = z.make(n)
- }
- copy(z, x)
- z[j] |= m
- // no need to normalize
- return z
- }
- panic("set bit is not 0 or 1")
-}
-
-// bit returns the value of the i'th bit, with lsb == bit 0.
-func (x nat) bit(i uint) uint {
- j := i / _W
- if j >= uint(len(x)) {
- return 0
- }
- // 0 <= j < len(x)
- return uint(x[j] >> (i % _W) & 1)
-}
-
-// sticky returns 1 if there's a 1 bit within the
-// i least significant bits, otherwise it returns 0.
-func (x nat) sticky(i uint) uint {
- j := i / _W
- if j >= uint(len(x)) {
- if len(x) == 0 {
- return 0
- }
- return 1
- }
- // 0 <= j < len(x)
- for _, x := range x[:j] {
- if x != 0 {
- return 1
- }
- }
- if x[j]<<(_W-i%_W) != 0 {
- return 1
- }
- return 0
-}
-
-func (z nat) and(x, y nat) nat {
- m := len(x)
- n := len(y)
- if m > n {
- m = n
- }
- // m <= n
-
- z = z.make(m)
- for i := 0; i < m; i++ {
- z[i] = x[i] & y[i]
- }
-
- return z.norm()
-}
-
-func (z nat) andNot(x, y nat) nat {
- m := len(x)
- n := len(y)
- if n > m {
- n = m
- }
- // m >= n
-
- z = z.make(m)
- for i := 0; i < n; i++ {
- z[i] = x[i] &^ y[i]
- }
- copy(z[n:m], x[n:m])
-
- return z.norm()
-}
-
-func (z nat) or(x, y nat) nat {
- m := len(x)
- n := len(y)
- s := x
- if m < n {
- n, m = m, n
- s = y
- }
- // m >= n
-
- z = z.make(m)
- for i := 0; i < n; i++ {
- z[i] = x[i] | y[i]
- }
- copy(z[n:m], s[n:m])
-
- return z.norm()
-}
-
-func (z nat) xor(x, y nat) nat {
- m := len(x)
- n := len(y)
- s := x
- if m < n {
- n, m = m, n
- s = y
- }
- // m >= n
-
- z = z.make(m)
- for i := 0; i < n; i++ {
- z[i] = x[i] ^ y[i]
- }
- copy(z[n:m], s[n:m])
-
- return z.norm()
-}
-
-// greaterThan reports whether (x1<<_W + x2) > (y1<<_W + y2)
-func greaterThan(x1, x2, y1, y2 Word) bool {
- return x1 > y1 || x1 == y1 && x2 > y2
-}
-
-// modW returns x % d.
-func (x nat) modW(d Word) (r Word) {
- // TODO(agl): we don't actually need to store the q value.
- var q nat
- q = q.make(len(x))
- return divWVW(q, 0, x, d)
-}
-
-// random creates a random integer in [0..limit), using the space in z if
-// possible. n is the bit length of limit.
-func (z nat) random(rand *rand.Rand, limit nat, n int) nat {
- if alias(z, limit) {
- z = nil // z is an alias for limit - cannot reuse
- }
- z = z.make(len(limit))
-
- bitLengthOfMSW := uint(n % _W)
- if bitLengthOfMSW == 0 {
- bitLengthOfMSW = _W
- }
- mask := Word((1 << bitLengthOfMSW) - 1)
-
- for {
- switch _W {
- case 32:
- for i := range z {
- z[i] = Word(rand.Uint32())
- }
- case 64:
- for i := range z {
- z[i] = Word(rand.Uint32()) | Word(rand.Uint32())<<32
- }
- default:
- panic("unknown word size")
- }
- z[len(limit)-1] &= mask
- if z.cmp(limit) < 0 {
- break
- }
- }
-
- return z.norm()
-}
-
-// If m != 0 (i.e., len(m) != 0), expNN sets z to x**y mod m;
-// otherwise it sets z to x**y. The result is the value of z.
-func (z nat) expNN(x, y, m nat) nat {
- if alias(z, x) || alias(z, y) {
- // We cannot allow in-place modification of x or y.
- z = nil
- }
-
- // x**y mod 1 == 0
- if len(m) == 1 && m[0] == 1 {
- return z.setWord(0)
- }
- // m == 0 || m > 1
-
- // x**0 == 1
- if len(y) == 0 {
- return z.setWord(1)
- }
- // y > 0
-
- // x**1 mod m == x mod m
- if len(y) == 1 && y[0] == 1 && len(m) != 0 {
- _, z = z.div(z, x, m)
- return z
- }
- // y > 1
-
- if len(m) != 0 {
- // We likely end up being as long as the modulus.
- z = z.make(len(m))
- }
- z = z.set(x)
-
- // If the base is non-trivial and the exponent is large, we use
- // 4-bit, windowed exponentiation. This involves precomputing 14 values
- // (x^2...x^15) but then reduces the number of multiply-reduces by a
- // third. Even for a 32-bit exponent, this reduces the number of
- // operations. Uses Montgomery method for odd moduli.
- if len(x) > 1 && len(y) > 1 && len(m) > 0 {
- if m[0]&1 == 1 {
- return z.expNNMontgomery(x, y, m)
- }
- return z.expNNWindowed(x, y, m)
- }
-
- v := y[len(y)-1] // v > 0 because y is normalized and y > 0
- shift := nlz(v) + 1
- v <<= shift
- var q nat
-
- const mask = 1 << (_W - 1)
-
- // We walk through the bits of the exponent one by one. Each time we
- // see a bit, we square, thus doubling the power. If the bit is a one,
- // we also multiply by x, thus adding one to the power.
-
- w := _W - int(shift)
- // zz and r are used to avoid allocating in mul and div as
- // otherwise the arguments would alias.
- var zz, r nat
- for j := 0; j < w; j++ {
- zz = zz.mul(z, z)
- zz, z = z, zz
-
- if v&mask != 0 {
- zz = zz.mul(z, x)
- zz, z = z, zz
- }
-
- if len(m) != 0 {
- zz, r = zz.div(r, z, m)
- zz, r, q, z = q, z, zz, r
- }
-
- v <<= 1
- }
-
- for i := len(y) - 2; i >= 0; i-- {
- v = y[i]
-
- for j := 0; j < _W; j++ {
- zz = zz.mul(z, z)
- zz, z = z, zz
-
- if v&mask != 0 {
- zz = zz.mul(z, x)
- zz, z = z, zz
- }
-
- if len(m) != 0 {
- zz, r = zz.div(r, z, m)
- zz, r, q, z = q, z, zz, r
- }
-
- v <<= 1
- }
- }
-
- return z.norm()
-}
-
-// expNNWindowed calculates x**y mod m using a fixed, 4-bit window.
-func (z nat) expNNWindowed(x, y, m nat) nat {
- // zz and r are used to avoid allocating in mul and div as otherwise
- // the arguments would alias.
- var zz, r nat
-
- const n = 4
- // powers[i] contains x^i.
- var powers [1 << n]nat
- powers[0] = natOne
- powers[1] = x
- for i := 2; i < 1<<n; i += 2 {
- p2, p, p1 := &powers[i/2], &powers[i], &powers[i+1]
- *p = p.mul(*p2, *p2)
- zz, r = zz.div(r, *p, m)
- *p, r = r, *p
- *p1 = p1.mul(*p, x)
- zz, r = zz.div(r, *p1, m)
- *p1, r = r, *p1
- }
-
- z = z.setWord(1)
-
- for i := len(y) - 1; i >= 0; i-- {
- yi := y[i]
- for j := 0; j < _W; j += n {
- if i != len(y)-1 || j != 0 {
- // Unrolled loop for significant performance
- // gain. Use go test -bench=".*" in crypto/rsa
- // to check performance before making changes.
- zz = zz.mul(z, z)
- zz, z = z, zz
- zz, r = zz.div(r, z, m)
- z, r = r, z
-
- zz = zz.mul(z, z)
- zz, z = z, zz
- zz, r = zz.div(r, z, m)
- z, r = r, z
-
- zz = zz.mul(z, z)
- zz, z = z, zz
- zz, r = zz.div(r, z, m)
- z, r = r, z
-
- zz = zz.mul(z, z)
- zz, z = z, zz
- zz, r = zz.div(r, z, m)
- z, r = r, z
- }
-
- zz = zz.mul(z, powers[yi>>(_W-n)])
- zz, z = z, zz
- zz, r = zz.div(r, z, m)
- z, r = r, z
-
- yi <<= n
- }
- }
-
- return z.norm()
-}
-
-// expNNMontgomery calculates x**y mod m using a fixed, 4-bit window.
-// Uses Montgomery representation.
-func (z nat) expNNMontgomery(x, y, m nat) nat {
- numWords := len(m)
-
- // We want the lengths of x and m to be equal.
- // It is OK if x >= m as long as len(x) == len(m).
- if len(x) > numWords {
- _, x = nat(nil).div(nil, x, m)
- // Note: now len(x) <= numWords, not guaranteed ==.
- }
- if len(x) < numWords {
- rr := make(nat, numWords)
- copy(rr, x)
- x = rr
- }
-
- // Ideally the precomputations would be performed outside, and reused
- // k0 = -m**-1 mod 2**_W. Algorithm from: Dumas, J.G. "On Newton–Raphson
- // Iteration for Multiplicative Inverses Modulo Prime Powers".
- k0 := 2 - m[0]
- t := m[0] - 1
- for i := 1; i < _W; i <<= 1 {
- t *= t
- k0 *= (t + 1)
- }
- k0 = -k0
-
- // 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)
- if len(RR) < numWords {
- zz = zz.make(numWords)
- copy(zz, RR)
- RR = zz
- }
- // one = 1, with equal length to that of m
- one := make(nat, numWords)
- one[0] = 1
-
- const n = 4
- // powers[i] contains x^i
- var powers [1 << n]nat
- powers[0] = powers[0].montgomery(one, RR, m, k0, numWords)
- powers[1] = powers[1].montgomery(x, RR, m, k0, numWords)
- for i := 2; i < 1<<n; i++ {
- powers[i] = powers[i].montgomery(powers[i-1], powers[1], m, k0, numWords)
- }
-
- // initialize z = 1 (Montgomery 1)
- z = z.make(numWords)
- copy(z, powers[0])
-
- zz = zz.make(numWords)
-
- // same windowed exponent, but with Montgomery multiplications
- for i := len(y) - 1; i >= 0; i-- {
- yi := y[i]
- for j := 0; j < _W; j += n {
- if i != len(y)-1 || j != 0 {
- zz = zz.montgomery(z, z, m, k0, numWords)
- z = z.montgomery(zz, zz, m, k0, numWords)
- zz = zz.montgomery(z, z, m, k0, numWords)
- z = z.montgomery(zz, zz, m, k0, numWords)
- }
- zz = zz.montgomery(z, powers[yi>>(_W-n)], m, k0, numWords)
- z, zz = zz, z
- yi <<= n
- }
- }
- // convert to regular number
- zz = zz.montgomery(z, one, m, k0, numWords)
-
- // One last reduction, just in case.
- // See golang.org/issue/13907.
- if zz.cmp(m) >= 0 {
- // Common case is m has high bit set; in that case,
- // since zz is the same length as m, there can be just
- // one multiple of m to remove. Just subtract.
- // We think that the subtract should be sufficient in general,
- // so do that unconditionally, but double-check,
- // in case our beliefs are wrong.
- // The div is not expected to be reached.
- zz = zz.sub(zz, m)
- if zz.cmp(m) >= 0 {
- _, zz = nat(nil).div(nil, zz, m)
- }
- }
-
- return zz.norm()
-}
-
-// probablyPrime performs n Miller-Rabin tests to check whether x is prime.
-// If x is prime, it returns true.
-// If x is not prime, it returns false with probability at least 1 - ¼ⁿ.
-//
-// It is not suitable for judging primes that an adversary may have crafted
-// to fool this test.
-func (n nat) probablyPrime(reps int) bool {
- if len(n) == 0 {
- return false
- }
-
- if len(n) == 1 {
- if n[0] < 2 {
- return false
- }
-
- if n[0]%2 == 0 {
- return n[0] == 2
- }
-
- // We have to exclude these cases because we reject all
- // multiples of these numbers below.
- switch n[0] {
- case 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53:
- return true
- }
- }
-
- if n[0]&1 == 0 {
- return false // n is even
- }
-
- const primesProduct32 = 0xC0CFD797 // Π {p ∈ primes, 2 < p <= 29}
- const primesProduct64 = 0xE221F97C30E94E1D // Π {p ∈ primes, 2 < p <= 53}
-
- var r Word
- switch _W {
- case 32:
- r = n.modW(primesProduct32)
- case 64:
- r = n.modW(primesProduct64 & _M)
- default:
- panic("Unknown word size")
- }
-
- if r%3 == 0 || r%5 == 0 || r%7 == 0 || r%11 == 0 ||
- r%13 == 0 || r%17 == 0 || r%19 == 0 || r%23 == 0 || r%29 == 0 {
- return false
- }
-
- if _W == 64 && (r%31 == 0 || r%37 == 0 || r%41 == 0 ||
- r%43 == 0 || r%47 == 0 || r%53 == 0) {
- return false
- }
-
- nm1 := nat(nil).sub(n, natOne)
- // determine q, k such that nm1 = q << k
- k := nm1.trailingZeroBits()
- q := nat(nil).shr(nm1, k)
-
- nm3 := nat(nil).sub(nm1, natTwo)
- rand := rand.New(rand.NewSource(int64(n[0])))
-
- var x, y, quotient nat
- nm3Len := nm3.bitLen()
-
-NextRandom:
- for i := 0; i < reps; i++ {
- x = x.random(rand, nm3, nm3Len)
- x = x.add(x, natTwo)
- y = y.expNN(x, q, n)
- if y.cmp(natOne) == 0 || y.cmp(nm1) == 0 {
- continue
- }
- for j := uint(1); j < k; j++ {
- y = y.mul(y, y)
- quotient, y = quotient.div(y, y, n)
- if y.cmp(nm1) == 0 {
- continue NextRandom
- }
- if y.cmp(natOne) == 0 {
- return false
- }
- }
- return false
- }
-
- return true
-}
-
-// bytes writes the value of z into buf using big-endian encoding.
-// len(buf) must be >= len(z)*_S. The value of z is encoded in the
-// slice buf[i:]. The number i of unused bytes at the beginning of
-// buf is returned as result.
-func (z nat) bytes(buf []byte) (i int) {
- i = len(buf)
- for _, d := range z {
- for j := 0; j < _S; j++ {
- i--
- buf[i] = byte(d)
- d >>= 8
- }
- }
-
- for i < len(buf) && buf[i] == 0 {
- i++
- }
-
- return
-}
-
-// 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
- }
- }
- if k < len(z) {
- z[k] = d
- }
-
- return z.norm()
-}
diff --git a/src/cmd/compile/internal/big/nat_test.go b/src/cmd/compile/internal/big/nat_test.go
deleted file mode 100644
index ebb2985..0000000
--- a/src/cmd/compile/internal/big/nat_test.go
+++ /dev/null
@@ -1,651 +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 big
-
-import (
- "fmt"
- "runtime"
- "strings"
- "testing"
-)
-
-var cmpTests = []struct {
- x, y nat
- r int
-}{
- {nil, nil, 0},
- {nil, nat(nil), 0},
- {nat(nil), nil, 0},
- {nat(nil), nat(nil), 0},
- {nat{0}, nat{0}, 0},
- {nat{0}, nat{1}, -1},
- {nat{1}, nat{0}, 1},
- {nat{1}, nat{1}, 0},
- {nat{0, _M}, nat{1}, 1},
- {nat{1}, nat{0, _M}, -1},
- {nat{1, _M}, nat{0, _M}, 1},
- {nat{0, _M}, nat{1, _M}, -1},
- {nat{16, 571956, 8794, 68}, nat{837, 9146, 1, 754489}, -1},
- {nat{34986, 41, 105, 1957}, nat{56, 7458, 104, 1957}, 1},
-}
-
-func TestCmp(t *testing.T) {
- for i, a := range cmpTests {
- r := a.x.cmp(a.y)
- if r != a.r {
- t.Errorf("#%d got r = %v; want %v", i, r, a.r)
- }
- }
-}
-
-type funNN func(z, x, y nat) nat
-type argNN struct {
- z, x, y nat
-}
-
-var sumNN = []argNN{
- {},
- {nat{1}, nil, nat{1}},
- {nat{1111111110}, nat{123456789}, nat{987654321}},
- {nat{0, 0, 0, 1}, nil, nat{0, 0, 0, 1}},
- {nat{0, 0, 0, 1111111110}, nat{0, 0, 0, 123456789}, nat{0, 0, 0, 987654321}},
- {nat{0, 0, 0, 1}, nat{0, 0, _M}, nat{0, 0, 1}},
-}
-
-var prodNN = []argNN{
- {},
- {nil, nil, nil},
- {nil, nat{991}, nil},
- {nat{991}, nat{991}, nat{1}},
- {nat{991 * 991}, nat{991}, nat{991}},
- {nat{0, 0, 991 * 991}, nat{0, 991}, nat{0, 991}},
- {nat{1 * 991, 2 * 991, 3 * 991, 4 * 991}, nat{1, 2, 3, 4}, nat{991}},
- {nat{4, 11, 20, 30, 20, 11, 4}, nat{1, 2, 3, 4}, nat{4, 3, 2, 1}},
- // 3^100 * 3^28 = 3^128
- {
- natFromString("11790184577738583171520872861412518665678211592275841109096961"),
- natFromString("515377520732011331036461129765621272702107522001"),
- natFromString("22876792454961"),
- },
- // z = 111....1 (70000 digits)
- // x = 10^(99*700) + ... + 10^1400 + 10^700 + 1
- // y = 111....1 (700 digits, larger than Karatsuba threshold on 32-bit and 64-bit)
- {
- natFromString(strings.Repeat("1", 70000)),
- natFromString("1" + strings.Repeat(strings.Repeat("0", 699)+"1", 99)),
- natFromString(strings.Repeat("1", 700)),
- },
- // z = 111....1 (20000 digits)
- // x = 10^10000 + 1
- // y = 111....1 (10000 digits)
- {
- natFromString(strings.Repeat("1", 20000)),
- natFromString("1" + strings.Repeat("0", 9999) + "1"),
- natFromString(strings.Repeat("1", 10000)),
- },
-}
-
-func natFromString(s string) nat {
- x, _, _, err := nat(nil).scan(strings.NewReader(s), 0, false)
- if err != nil {
- panic(err)
- }
- return x
-}
-
-func TestSet(t *testing.T) {
- for _, a := range sumNN {
- z := nat(nil).set(a.z)
- if z.cmp(a.z) != 0 {
- t.Errorf("got z = %v; want %v", z, a.z)
- }
- }
-}
-
-func testFunNN(t *testing.T, msg string, f funNN, a argNN) {
- z := f(nil, a.x, a.y)
- if z.cmp(a.z) != 0 {
- t.Errorf("%s%+v\n\tgot z = %v; want %v", msg, a, z, a.z)
- }
-}
-
-func TestFunNN(t *testing.T) {
- for _, a := range sumNN {
- arg := a
- testFunNN(t, "add", nat.add, arg)
-
- arg = argNN{a.z, a.y, a.x}
- testFunNN(t, "add symmetric", nat.add, arg)
-
- arg = argNN{a.x, a.z, a.y}
- testFunNN(t, "sub", nat.sub, arg)
-
- arg = argNN{a.y, a.z, a.x}
- testFunNN(t, "sub symmetric", nat.sub, arg)
- }
-
- for _, a := range prodNN {
- arg := a
- testFunNN(t, "mul", nat.mul, arg)
-
- arg = argNN{a.z, a.y, a.x}
- testFunNN(t, "mul symmetric", nat.mul, arg)
- }
-}
-
-var mulRangesN = []struct {
- a, b uint64
- prod string
-}{
- {0, 0, "0"},
- {1, 1, "1"},
- {1, 2, "2"},
- {1, 3, "6"},
- {10, 10, "10"},
- {0, 100, "0"},
- {0, 1e9, "0"},
- {1, 0, "1"}, // empty range
- {100, 1, "1"}, // empty range
- {1, 10, "3628800"}, // 10!
- {1, 20, "2432902008176640000"}, // 20!
- {1, 100,
- "933262154439441526816992388562667004907159682643816214685929" +
- "638952175999932299156089414639761565182862536979208272237582" +
- "51185210916864000000000000000000000000", // 100!
- },
-}
-
-func TestMulRangeN(t *testing.T) {
- for i, r := range mulRangesN {
- prod := string(nat(nil).mulRange(r.a, r.b).utoa(10))
- if prod != r.prod {
- t.Errorf("#%d: got %s; want %s", i, prod, r.prod)
- }
- }
-}
-
-// allocBytes returns the number of bytes allocated by invoking f.
-func allocBytes(f func()) uint64 {
- var stats runtime.MemStats
- runtime.ReadMemStats(&stats)
- t := stats.TotalAlloc
- f()
- runtime.ReadMemStats(&stats)
- return stats.TotalAlloc - t
-}
-
-// TestMulUnbalanced tests that multiplying numbers of different lengths
-// does not cause deep recursion and in turn allocate too much memory.
-// Test case for issue 3807.
-func TestMulUnbalanced(t *testing.T) {
- defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
- x := rndNat(50000)
- y := rndNat(40)
- allocSize := allocBytes(func() {
- nat(nil).mul(x, y)
- })
- inputSize := uint64(len(x)+len(y)) * _S
- if ratio := allocSize / uint64(inputSize); ratio > 10 {
- t.Errorf("multiplication uses too much memory (%d > %d times the size of inputs)", allocSize, ratio)
- }
-}
-
-func rndNat(n int) nat {
- return nat(rndV(n)).norm()
-}
-
-func BenchmarkMul(b *testing.B) {
- mulx := rndNat(1e4)
- muly := rndNat(1e4)
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- var z nat
- z.mul(mulx, muly)
- }
-}
-
-func TestNLZ(t *testing.T) {
- var x Word = _B >> 1
- for i := 0; i <= _W; i++ {
- if int(nlz(x)) != i {
- t.Errorf("failed at %x: got %d want %d", x, nlz(x), i)
- }
- x >>= 1
- }
-}
-
-type shiftTest struct {
- in nat
- shift uint
- out nat
-}
-
-var leftShiftTests = []shiftTest{
- {nil, 0, nil},
- {nil, 1, nil},
- {natOne, 0, natOne},
- {natOne, 1, natTwo},
- {nat{1 << (_W - 1)}, 1, nat{0}},
- {nat{1 << (_W - 1), 0}, 1, nat{0, 1}},
-}
-
-func TestShiftLeft(t *testing.T) {
- for i, test := range leftShiftTests {
- var z nat
- z = z.shl(test.in, test.shift)
- for j, d := range test.out {
- if j >= len(z) || z[j] != d {
- t.Errorf("#%d: got: %v want: %v", i, z, test.out)
- break
- }
- }
- }
-}
-
-var rightShiftTests = []shiftTest{
- {nil, 0, nil},
- {nil, 1, nil},
- {natOne, 0, natOne},
- {natOne, 1, nil},
- {natTwo, 1, natOne},
- {nat{0, 1}, 1, nat{1 << (_W - 1)}},
- {nat{2, 1, 1}, 1, nat{1<<(_W-1) + 1, 1 << (_W - 1)}},
-}
-
-func TestShiftRight(t *testing.T) {
- for i, test := range rightShiftTests {
- var z nat
- z = z.shr(test.in, test.shift)
- for j, d := range test.out {
- if j >= len(z) || z[j] != d {
- t.Errorf("#%d: got: %v want: %v", i, z, test.out)
- break
- }
- }
- }
-}
-
-type modWTest struct {
- in string
- dividend string
- out string
-}
-
-var modWTests32 = []modWTest{
- {"23492635982634928349238759823742", "252341", "220170"},
-}
-
-var modWTests64 = []modWTest{
- {"6527895462947293856291561095690465243862946", "524326975699234", "375066989628668"},
-}
-
-func runModWTests(t *testing.T, tests []modWTest) {
- for i, test := range tests {
- in, _ := new(Int).SetString(test.in, 10)
- d, _ := new(Int).SetString(test.dividend, 10)
- out, _ := new(Int).SetString(test.out, 10)
-
- r := in.abs.modW(d.abs[0])
- if r != out.abs[0] {
- t.Errorf("#%d failed: got %d want %s", i, r, out)
- }
- }
-}
-
-func TestModW(t *testing.T) {
- if _W >= 32 {
- runModWTests(t, modWTests32)
- }
- if _W >= 64 {
- runModWTests(t, modWTests64)
- }
-}
-
-func TestTrailingZeroBits(t *testing.T) {
- // test 0 case explicitly
- if n := trailingZeroBits(0); n != 0 {
- t.Errorf("got trailingZeroBits(0) = %d; want 0", n)
- }
-
- x := Word(1)
- for i := uint(0); i < _W; i++ {
- n := trailingZeroBits(x)
- if n != i {
- t.Errorf("got trailingZeroBits(%#x) = %d; want %d", x, n, i%_W)
- }
- x <<= 1
- }
-
- // test 0 case explicitly
- if n := nat(nil).trailingZeroBits(); n != 0 {
- t.Errorf("got nat(nil).trailingZeroBits() = %d; want 0", n)
- }
-
- y := nat(nil).set(natOne)
- for i := uint(0); i <= 3*_W; i++ {
- n := y.trailingZeroBits()
- if n != i {
- t.Errorf("got 0x%s.trailingZeroBits() = %d; want %d", y.utoa(16), n, i)
- }
- y = y.shl(y, 1)
- }
-}
-
-var montgomeryTests = []struct {
- x, y, m string
- k0 uint64
- out32, out64 string
-}{
- {
- "0xffffffffffffffffffffffffffffffffffffffffffffffffe",
- "0xffffffffffffffffffffffffffffffffffffffffffffffffe",
- "0xfffffffffffffffffffffffffffffffffffffffffffffffff",
- 1,
- "0x1000000000000000000000000000000000000000000",
- "0x10000000000000000000000000000000000",
- },
- {
- "0x000000000ffffff5",
- "0x000000000ffffff0",
- "0x0000000010000001",
- 0xff0000000fffffff,
- "0x000000000bfffff4",
- "0x0000000003400001",
- },
- {
- "0x0000000080000000",
- "0x00000000ffffffff",
- "0x1000000000000001",
- 0xfffffffffffffff,
- "0x0800000008000001",
- "0x0800000008000001",
- },
- {
- "0x0000000080000000",
- "0x0000000080000000",
- "0xffffffff00000001",
- 0xfffffffeffffffff,
- "0xbfffffff40000001",
- "0xbfffffff40000001",
- },
- {
- "0x0000000080000000",
- "0x0000000080000000",
- "0x00ffffff00000001",
- 0xfffffeffffffff,
- "0xbfffff40000001",
- "0xbfffff40000001",
- },
- {
- "0x0000000080000000",
- "0x0000000080000000",
- "0x0000ffff00000001",
- 0xfffeffffffff,
- "0xbfff40000001",
- "0xbfff40000001",
- },
- {
- "0x3321ffffffffffffffffffffffffffff00000000000022222623333333332bbbb888c0",
- "0x3321ffffffffffffffffffffffffffff00000000000022222623333333332bbbb888c0",
- "0x33377fffffffffffffffffffffffffffffffffffffffffffff0000000000022222eee1",
- 0xdecc8f1249812adf,
- "0x04eb0e11d72329dc0915f86784820fc403275bf2f6620a20e0dd344c5cd0875e50deb5",
- "0x0d7144739a7d8e11d72329dc0915f86784820fc403275bf2f61ed96f35dd34dbb3d6a0",
- },
- {
- "0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000022222223333333333444444444",
- "0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffff999999999999999aaabbbbbbbbcccccccccccc",
- "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff33377fffffffffffffffffffffffffffffffffffffffffffff0000000000022222eee1",
- 0xdecc8f1249812adf,
- "0x5c0d52f451aec609b15da8e5e5626c4eaa88723bdeac9d25ca9b961269400410ca208a16af9c2fb07d7a11c7772cba02c22f9711078d51a3797eb18e691295293284d988e349fa6deba46b25a4ecd9f715",
- "0x92fcad4b5c0d52f451aec609b15da8e5e5626c4eaa88723bdeac9d25ca9b961269400410ca208a16af9c2fb07d799c32fe2f3cc5422f9711078d51a3797eb18e691295293284d8f5e69caf6decddfe1df6",
- },
-}
-
-func TestMontgomery(t *testing.T) {
- one := NewInt(1)
- _B := new(Int).Lsh(one, _W)
- for i, test := range montgomeryTests {
- x := natFromString(test.x)
- y := natFromString(test.y)
- m := natFromString(test.m)
- for len(x) < len(m) {
- x = append(x, 0)
- }
- for len(y) < len(m) {
- y = append(y, 0)
- }
-
- if x.cmp(m) > 0 {
- _, r := nat(nil).div(nil, x, m)
- t.Errorf("#%d: x > m (0x%s > 0x%s; use 0x%s)", i, x.utoa(16), m.utoa(16), r.utoa(16))
- }
- if y.cmp(m) > 0 {
- _, r := nat(nil).div(nil, x, m)
- t.Errorf("#%d: y > m (0x%s > 0x%s; use 0x%s)", i, y.utoa(16), m.utoa(16), r.utoa(16))
- }
-
- var out nat
- if _W == 32 {
- out = natFromString(test.out32)
- } else {
- out = natFromString(test.out64)
- }
-
- // t.Logf("#%d: len=%d\n", i, len(m))
-
- // check output in table
- xi := &Int{abs: x}
- yi := &Int{abs: y}
- mi := &Int{abs: m}
- p := new(Int).Mod(new(Int).Mul(xi, new(Int).Mul(yi, new(Int).ModInverse(new(Int).Lsh(one, uint(len(m))*_W), mi))), mi)
- if out.cmp(p.abs.norm()) != 0 {
- t.Errorf("#%d: out in table=0x%s, computed=0x%s", i, out.utoa(16), p.abs.norm().utoa(16))
- }
-
- // check k0 in table
- k := new(Int).Mod(&Int{abs: m}, _B)
- k = new(Int).Sub(_B, k)
- k = new(Int).Mod(k, _B)
- k0 := Word(new(Int).ModInverse(k, _B).Uint64())
- if k0 != Word(test.k0) {
- t.Errorf("#%d: k0 in table=%#x, computed=%#x\n", i, test.k0, k0)
- }
-
- // check montgomery with correct k0 produces correct output
- z := nat(nil).montgomery(x, y, m, k0, len(m))
- z = z.norm()
- if z.cmp(out) != 0 {
- t.Errorf("#%d: got 0x%s want 0x%s", i, z.utoa(16), out.utoa(16))
- }
- }
-}
-
-var expNNTests = []struct {
- x, y, m string
- out string
-}{
- {"0", "0", "0", "1"},
- {"0", "0", "1", "0"},
- {"1", "1", "1", "0"},
- {"2", "1", "1", "0"},
- {"2", "2", "1", "0"},
- {"10", "100000000000", "1", "0"},
- {"0x8000000000000000", "2", "", "0x40000000000000000000000000000000"},
- {"0x8000000000000000", "2", "6719", "4944"},
- {"0x8000000000000000", "3", "6719", "5447"},
- {"0x8000000000000000", "1000", "6719", "1603"},
- {"0x8000000000000000", "1000000", "6719", "3199"},
- {
- "2938462938472983472983659726349017249287491026512746239764525612965293865296239471239874193284792387498274256129746192347",
- "298472983472983471903246121093472394872319615612417471234712061",
- "29834729834729834729347290846729561262544958723956495615629569234729836259263598127342374289365912465901365498236492183464",
- "23537740700184054162508175125554701713153216681790245129157191391322321508055833908509185839069455749219131480588829346291",
- },
- {
- "11521922904531591643048817447554701904414021819823889996244743037378330903763518501116638828335352811871131385129455853417360623007349090150042001944696604737499160174391019030572483602867266711107136838523916077674888297896995042968746762200926853379",
- "426343618817810911523",
- "444747819283133684179",
- "42",
- },
-}
-
-func TestExpNN(t *testing.T) {
- for i, test := range expNNTests {
- x := natFromString(test.x)
- y := natFromString(test.y)
- out := natFromString(test.out)
-
- var m nat
- if len(test.m) > 0 {
- m = natFromString(test.m)
- }
-
- z := nat(nil).expNN(x, y, m)
- if z.cmp(out) != 0 {
- t.Errorf("#%d got %s want %s", i, z.utoa(10), out.utoa(10))
- }
- }
-}
-
-func BenchmarkExp3Power(b *testing.B) {
- const x = 3
- for _, y := range []Word{
- 0x10, 0x40, 0x100, 0x400, 0x1000, 0x4000, 0x10000, 0x40000, 0x100000, 0x400000,
- } {
- b.Run(fmt.Sprintf("%#x", y), func(b *testing.B) {
- var z nat
- for i := 0; i < b.N; i++ {
- z.expWW(x, y)
- }
- })
- }
-}
-
-func fibo(n int) nat {
- switch n {
- case 0:
- return nil
- case 1:
- return nat{1}
- }
- f0 := fibo(0)
- f1 := fibo(1)
- var f2 nat
- for i := 1; i < n; i++ {
- f2 = f2.add(f0, f1)
- f0, f1, f2 = f1, f2, f0
- }
- return f1
-}
-
-var fiboNums = []string{
- "0",
- "55",
- "6765",
- "832040",
- "102334155",
- "12586269025",
- "1548008755920",
- "190392490709135",
- "23416728348467685",
- "2880067194370816120",
- "354224848179261915075",
-}
-
-func TestFibo(t *testing.T) {
- for i, want := range fiboNums {
- n := i * 10
- got := string(fibo(n).utoa(10))
- if got != want {
- t.Errorf("fibo(%d) failed: got %s want %s", n, got, want)
- }
- }
-}
-
-func BenchmarkFibo(b *testing.B) {
- for i := 0; i < b.N; i++ {
- fibo(1e0)
- fibo(1e1)
- fibo(1e2)
- fibo(1e3)
- fibo(1e4)
- fibo(1e5)
- }
-}
-
-var bitTests = []struct {
- x string
- i uint
- want uint
-}{
- {"0", 0, 0},
- {"0", 1, 0},
- {"0", 1000, 0},
-
- {"0x1", 0, 1},
- {"0x10", 0, 0},
- {"0x10", 3, 0},
- {"0x10", 4, 1},
- {"0x10", 5, 0},
-
- {"0x8000000000000000", 62, 0},
- {"0x8000000000000000", 63, 1},
- {"0x8000000000000000", 64, 0},
-
- {"0x3" + strings.Repeat("0", 32), 127, 0},
- {"0x3" + strings.Repeat("0", 32), 128, 1},
- {"0x3" + strings.Repeat("0", 32), 129, 1},
- {"0x3" + strings.Repeat("0", 32), 130, 0},
-}
-
-func TestBit(t *testing.T) {
- for i, test := range bitTests {
- x := natFromString(test.x)
- if got := x.bit(test.i); got != test.want {
- t.Errorf("#%d: %s.bit(%d) = %v; want %v", i, test.x, test.i, got, test.want)
- }
- }
-}
-
-var stickyTests = []struct {
- x string
- i uint
- want uint
-}{
- {"0", 0, 0},
- {"0", 1, 0},
- {"0", 1000, 0},
-
- {"0x1", 0, 0},
- {"0x1", 1, 1},
-
- {"0x1350", 0, 0},
- {"0x1350", 4, 0},
- {"0x1350", 5, 1},
-
- {"0x8000000000000000", 63, 0},
- {"0x8000000000000000", 64, 1},
-
- {"0x1" + strings.Repeat("0", 100), 400, 0},
- {"0x1" + strings.Repeat("0", 100), 401, 1},
-}
-
-func TestSticky(t *testing.T) {
- for i, test := range stickyTests {
- x := natFromString(test.x)
- if got := x.sticky(test.i); got != test.want {
- t.Errorf("#%d: %s.sticky(%d) = %v; want %v", i, test.x, test.i, got, test.want)
- }
- if test.want == 1 {
- // all subsequent i's should also return 1
- for d := uint(1); d <= 3; d++ {
- if got := x.sticky(test.i + d); got != 1 {
- t.Errorf("#%d: %s.sticky(%d) = %v; want %v", i, test.x, test.i+d, got, 1)
- }
- }
- }
- }
-}
diff --git a/src/cmd/compile/internal/big/natconv.go b/src/cmd/compile/internal/big/natconv.go
deleted file mode 100644
index 4454784..0000000
--- a/src/cmd/compile/internal/big/natconv.go
+++ /dev/null
@@ -1,492 +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.
-
-// This file implements nat-to-string conversion functions.
-
-package big
-
-import (
- "errors"
- "fmt"
- "io"
- "math"
- "sync"
-)
-
-const digits = "0123456789abcdefghijklmnopqrstuvwxyz"
-
-// Note: MaxBase = len(digits), but it must remain a rune constant
-// for API compatibility.
-
-// MaxBase is the largest number base accepted for string conversions.
-const MaxBase = 'z' - 'a' + 10 + 1
-
-// maxPow returns (b**n, n) such that b**n is the largest power b**n <= _M.
-// For instance maxPow(10) == (1e19, 19) for 19 decimal digits in a 64bit Word.
-// In other words, at most n digits in base b fit into a Word.
-// TODO(gri) replace this with a table, generated at build time.
-func maxPow(b Word) (p Word, n int) {
- p, n = b, 1 // assuming b <= _M
- for max := _M / b; p <= max; {
- // p == b**n && p <= max
- p *= b
- n++
- }
- // p == b**n && p <= _M
- return
-}
-
-// pow returns x**n for n > 0, and 1 otherwise.
-func pow(x Word, n int) (p Word) {
- // n == sum of bi * 2**i, for 0 <= i < imax, and bi is 0 or 1
- // thus x**n == product of x**(2**i) for all i where bi == 1
- // (Russian Peasant Method for exponentiation)
- p = 1
- for n > 0 {
- if n&1 != 0 {
- p *= x
- }
- x *= x
- n >>= 1
- }
- return
-}
-
-// scan scans the number corresponding to the longest possible prefix
-// from r representing an unsigned number in a given conversion base.
-// It returns the corresponding natural number res, the actual base b,
-// a digit count, and a read or syntax error err, if any.
-//
-// number = [ prefix ] mantissa .
-// prefix = "0" [ "x" | "X" | "b" | "B" ] .
-// mantissa = digits | digits "." [ digits ] | "." digits .
-// digits = digit { digit } .
-// digit = "0" ... "9" | "a" ... "z" | "A" ... "Z" .
-//
-// Unless fracOk is set, the base argument must be 0 or a value between
-// 2 and MaxBase. If fracOk is set, the base argument must be one of
-// 0, 2, 10, or 16. Providing an invalid base argument leads to a run-
-// time panic.
-//
-// For base 0, the number prefix determines the actual base: A prefix of
-// ``0x'' or ``0X'' selects base 16; if fracOk is not set, the ``0'' prefix
-// selects base 8, and a ``0b'' or ``0B'' prefix selects base 2. Otherwise
-// the selected base is 10 and no prefix is accepted.
-//
-// If fracOk is set, an octal prefix is ignored (a leading ``0'' simply
-// stands for a zero digit), and a period followed by a fractional part
-// is permitted. The result value is computed as if there were no period
-// present; and the count value is used to determine the fractional part.
-//
-// A result digit count > 0 corresponds to the number of (non-prefix) digits
-// parsed. A digit count <= 0 indicates the presence of a period (if fracOk
-// is set, only), and -count is the number of fractional digits found.
-// In this case, the actual value of the scanned number is res * b**count.
-//
-func (z nat) scan(r io.ByteScanner, base int, fracOk bool) (res nat, b, count int, err error) {
- // reject illegal bases
- baseOk := base == 0 ||
- !fracOk && 2 <= base && base <= MaxBase ||
- fracOk && (base == 2 || base == 10 || base == 16)
- if !baseOk {
- panic(fmt.Sprintf("illegal number base %d", base))
- }
-
- // one char look-ahead
- ch, err := r.ReadByte()
- if err != nil {
- return
- }
-
- // determine actual base
- b = base
- if base == 0 {
- // actual base is 10 unless there's a base prefix
- b = 10
- if ch == '0' {
- count = 1
- switch ch, err = r.ReadByte(); err {
- case nil:
- // possibly one of 0x, 0X, 0b, 0B
- if !fracOk {
- b = 8
- }
- switch ch {
- case 'x', 'X':
- b = 16
- case 'b', 'B':
- b = 2
- }
- switch b {
- case 16, 2:
- count = 0 // prefix is not counted
- if ch, err = r.ReadByte(); err != nil {
- // io.EOF is also an error in this case
- return
- }
- case 8:
- count = 0 // prefix is not counted
- }
- case io.EOF:
- // input is "0"
- res = z[:0]
- err = nil
- return
- default:
- // read error
- return
- }
- }
- }
-
- // convert string
- // Algorithm: Collect digits in groups of at most n digits in di
- // and then use mulAddWW for every such group to add them to the
- // result.
- z = z[:0]
- b1 := Word(b)
- bn, n := maxPow(b1) // at most n digits in base b1 fit into Word
- di := Word(0) // 0 <= di < b1**i < bn
- i := 0 // 0 <= i < n
- dp := -1 // position of decimal point
- for {
- if fracOk && ch == '.' {
- fracOk = false
- dp = count
- // advance
- if ch, err = r.ReadByte(); err != nil {
- if err == io.EOF {
- err = nil
- break
- }
- return
- }
- }
-
- // convert rune into digit value d1
- var d1 Word
- switch {
- case '0' <= ch && ch <= '9':
- d1 = Word(ch - '0')
- case 'a' <= ch && ch <= 'z':
- d1 = Word(ch - 'a' + 10)
- case 'A' <= ch && ch <= 'Z':
- d1 = Word(ch - 'A' + 10)
- default:
- d1 = MaxBase + 1
- }
- if d1 >= b1 {
- r.UnreadByte() // ch does not belong to number anymore
- break
- }
- count++
-
- // collect d1 in di
- di = di*b1 + d1
- i++
-
- // if di is "full", add it to the result
- if i == n {
- z = z.mulAddWW(z, bn, di)
- di = 0
- i = 0
- }
-
- // advance
- if ch, err = r.ReadByte(); err != nil {
- if err == io.EOF {
- err = nil
- break
- }
- return
- }
- }
-
- if count == 0 {
- // no digits found
- switch {
- case base == 0 && b == 8:
- // there was only the octal prefix 0 (possibly followed by digits > 7);
- // count as one digit and return base 10, not 8
- count = 1
- b = 10
- case base != 0 || b != 8:
- // there was neither a mantissa digit nor the octal prefix 0
- err = errors.New("syntax error scanning number")
- }
- return
- }
- // count > 0
-
- // add remaining digits to result
- if i > 0 {
- z = z.mulAddWW(z, pow(b1, i), di)
- }
- res = z.norm()
-
- // adjust for fraction, if any
- if dp >= 0 {
- // 0 <= dp <= count > 0
- count = dp - count
- }
-
- return
-}
-
-// utoa converts x to an ASCII representation in the given base;
-// base must be between 2 and MaxBase, inclusive.
-func (x nat) utoa(base int) []byte {
- return x.itoa(false, base)
-}
-
-// itoa is like utoa but it prepends a '-' if neg && x != 0.
-func (x nat) itoa(neg bool, base int) []byte {
- if base < 2 || base > MaxBase {
- panic("invalid base")
- }
-
- // x == 0
- if len(x) == 0 {
- return []byte("0")
- }
- // len(x) > 0
-
- // allocate buffer for conversion
- i := int(float64(x.bitLen())/math.Log2(float64(base))) + 1 // off by 1 at most
- if neg {
- i++
- }
- s := make([]byte, i)
-
- // convert power of two and non power of two bases separately
- if b := Word(base); b == b&-b {
- // shift is base b digit size in bits
- shift := trailingZeroBits(b) // shift > 0 because b >= 2
- mask := Word(1<<shift - 1)
- w := x[0] // current word
- nbits := uint(_W) // number of unprocessed bits in w
-
- // convert less-significant words (include leading zeros)
- for k := 1; k < len(x); k++ {
- // convert full digits
- for nbits >= shift {
- i--
- s[i] = digits[w&mask]
- w >>= shift
- nbits -= shift
- }
-
- // convert any partial leading digit and advance to next word
- if nbits == 0 {
- // no partial digit remaining, just advance
- w = x[k]
- nbits = _W
- } else {
- // partial digit in current word w (== x[k-1]) and next word x[k]
- w |= x[k] << nbits
- i--
- s[i] = digits[w&mask]
-
- // advance
- w = x[k] >> (shift - nbits)
- nbits = _W - (shift - nbits)
- }
- }
-
- // convert digits of most-significant word w (omit leading zeros)
- for w != 0 {
- i--
- s[i] = digits[w&mask]
- w >>= shift
- }
-
- } else {
- bb, ndigits := maxPow(b)
-
- // construct table of successive squares of bb*leafSize to use in subdivisions
- // result (table != nil) <=> (len(x) > leafSize > 0)
- table := divisors(len(x), b, ndigits, bb)
-
- // preserve x, create local copy for use by convertWords
- q := nat(nil).set(x)
-
- // convert q to string s in base b
- q.convertWords(s, b, ndigits, bb, table)
-
- // strip leading zeros
- // (x != 0; thus s must contain at least one non-zero digit
- // and the loop will terminate)
- i = 0
- for s[i] == '0' {
- i++
- }
- }
-
- if neg {
- i--
- s[i] = '-'
- }
-
- return s[i:]
-}
-
-// Convert words of q to base b digits in s. If q is large, it is recursively "split in half"
-// by nat/nat division using tabulated divisors. Otherwise, it is converted iteratively using
-// repeated nat/Word division.
-//
-// The iterative method processes n Words by n divW() calls, each of which visits every Word in the
-// incrementally shortened q for a total of n + (n-1) + (n-2) ... + 2 + 1, or n(n+1)/2 divW()'s.
-// Recursive conversion divides q by its approximate square root, yielding two parts, each half
-// the size of q. Using the iterative method on both halves means 2 * (n/2)(n/2 + 1)/2 divW()'s
-// plus the expensive long div(). Asymptotically, the ratio is favorable at 1/2 the divW()'s, and
-// is made better by splitting the subblocks recursively. Best is to split blocks until one more
-// split would take longer (because of the nat/nat div()) than the twice as many divW()'s of the
-// iterative approach. This threshold is represented by leafSize. Benchmarking of leafSize in the
-// range 2..64 shows that values of 8 and 16 work well, with a 4x speedup at medium lengths and
-// ~30x for 20000 digits. Use nat_test.go's BenchmarkLeafSize tests to optimize leafSize for
-// specific hardware.
-//
-func (q nat) convertWords(s []byte, b Word, ndigits int, bb Word, table []divisor) {
- // split larger blocks recursively
- if table != nil {
- // len(q) > leafSize > 0
- var r nat
- index := len(table) - 1
- for len(q) > leafSize {
- // find divisor close to sqrt(q) if possible, but in any case < q
- maxLength := q.bitLen() // ~= log2 q, or at of least largest possible q of this bit length
- minLength := maxLength >> 1 // ~= log2 sqrt(q)
- for index > 0 && table[index-1].nbits > minLength {
- index-- // desired
- }
- if table[index].nbits >= maxLength && table[index].bbb.cmp(q) >= 0 {
- index--
- if index < 0 {
- panic("internal inconsistency")
- }
- }
-
- // split q into the two digit number (q'*bbb + r) to form independent subblocks
- q, r = q.div(r, q, table[index].bbb)
-
- // convert subblocks and collect results in s[:h] and s[h:]
- h := len(s) - table[index].ndigits
- r.convertWords(s[h:], b, ndigits, bb, table[0:index])
- s = s[:h] // == q.convertWords(s, b, ndigits, bb, table[0:index+1])
- }
- }
-
- // having split any large blocks now process the remaining (small) block iteratively
- i := len(s)
- var r Word
- if b == 10 {
- // hard-coding for 10 here speeds this up by 1.25x (allows for / and % by constants)
- for len(q) > 0 {
- // extract least significant, base bb "digit"
- q, r = q.divW(q, bb)
- for j := 0; j < ndigits && i > 0; j++ {
- i--
- // avoid % computation since r%10 == r - int(r/10)*10;
- // this appears to be faster for BenchmarkString10000Base10
- // and smaller strings (but a bit slower for larger ones)
- t := r / 10
- s[i] = '0' + byte(r-t*10)
- r = t
- }
- }
- } else {
- for len(q) > 0 {
- // extract least significant, base bb "digit"
- q, r = q.divW(q, bb)
- for j := 0; j < ndigits && i > 0; j++ {
- i--
- s[i] = digits[r%b]
- r /= b
- }
- }
- }
-
- // prepend high-order zeros
- for i > 0 { // while need more leading zeros
- i--
- s[i] = '0'
- }
-}
-
-// Split blocks greater than leafSize Words (or set to 0 to disable recursive conversion)
-// Benchmark and configure leafSize using: go test -bench="Leaf"
-// 8 and 16 effective on 3.0 GHz Xeon "Clovertown" CPU (128 byte cache lines)
-// 8 and 16 effective on 2.66 GHz Core 2 Duo "Penryn" CPU
-var leafSize int = 8 // number of Word-size binary values treat as a monolithic block
-
-type divisor struct {
- bbb nat // divisor
- nbits int // bit length of divisor (discounting leading zeros) ~= log2(bbb)
- ndigits int // digit length of divisor in terms of output base digits
-}
-
-var cacheBase10 struct {
- sync.Mutex
- table [64]divisor // cached divisors for base 10
-}
-
-// expWW computes x**y
-func (z nat) expWW(x, y Word) nat {
- return z.expNN(nat(nil).setWord(x), nat(nil).setWord(y), nil)
-}
-
-// construct table of powers of bb*leafSize to use in subdivisions
-func divisors(m int, b Word, ndigits int, bb Word) []divisor {
- // only compute table when recursive conversion is enabled and x is large
- if leafSize == 0 || m <= leafSize {
- return nil
- }
-
- // determine k where (bb**leafSize)**(2**k) >= sqrt(x)
- k := 1
- for words := leafSize; words < m>>1 && k < len(cacheBase10.table); words <<= 1 {
- k++
- }
-
- // reuse and extend existing table of divisors or create new table as appropriate
- var table []divisor // for b == 10, table overlaps with cacheBase10.table
- if b == 10 {
- cacheBase10.Lock()
- table = cacheBase10.table[0:k] // reuse old table for this conversion
- } else {
- table = make([]divisor, k) // create new table for this conversion
- }
-
- // extend table
- if table[k-1].ndigits == 0 {
- // add new entries as needed
- var larger nat
- for i := 0; i < k; i++ {
- if table[i].ndigits == 0 {
- if i == 0 {
- table[0].bbb = nat(nil).expWW(bb, Word(leafSize))
- table[0].ndigits = ndigits * leafSize
- } else {
- table[i].bbb = nat(nil).mul(table[i-1].bbb, table[i-1].bbb)
- table[i].ndigits = 2 * table[i-1].ndigits
- }
-
- // optimization: exploit aggregated extra bits in macro blocks
- larger = nat(nil).set(table[i].bbb)
- for mulAddVWW(larger, larger, b, 0) == 0 {
- table[i].bbb = table[i].bbb.set(larger)
- table[i].ndigits++
- }
-
- table[i].nbits = table[i].bbb.bitLen()
- }
- }
- }
-
- if b == 10 {
- cacheBase10.Unlock()
- }
-
- return table
-}
diff --git a/src/cmd/compile/internal/big/natconv_test.go b/src/cmd/compile/internal/big/natconv_test.go
deleted file mode 100644
index 79901d1..0000000
--- a/src/cmd/compile/internal/big/natconv_test.go
+++ /dev/null
@@ -1,379 +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.
-
-package big
-
-import (
- "bytes"
- "fmt"
- "io"
- "strings"
- "testing"
-)
-
-func itoa(x nat, base int) []byte {
- // special cases
- switch {
- case base < 2:
- panic("illegal base")
- case len(x) == 0:
- return []byte("0")
- }
-
- // allocate buffer for conversion
- i := x.bitLen()/log2(Word(base)) + 1 // +1: round up
- s := make([]byte, i)
-
- // don't destroy x
- q := nat(nil).set(x)
-
- // convert
- for len(q) > 0 {
- i--
- var r Word
- q, r = q.divW(q, Word(base))
- s[i] = digits[r]
- }
-
- return s[i:]
-}
-
-var strTests = []struct {
- x nat // nat value to be converted
- b int // conversion base
- s string // expected result
-}{
- {nil, 2, "0"},
- {nat{1}, 2, "1"},
- {nat{0xc5}, 2, "11000101"},
- {nat{03271}, 8, "3271"},
- {nat{10}, 10, "10"},
- {nat{1234567890}, 10, "1234567890"},
- {nat{0xdeadbeef}, 16, "deadbeef"},
- {nat{0x229be7}, 17, "1a2b3c"},
- {nat{0x309663e6}, 32, "o9cov6"},
-}
-
-func TestString(t *testing.T) {
- // test invalid base explicitly
- var panicStr string
- func() {
- defer func() {
- panicStr = recover().(string)
- }()
- natOne.utoa(1)
- }()
- if panicStr != "invalid base" {
- t.Errorf("expected panic for invalid base")
- }
-
- for _, a := range strTests {
- s := string(a.x.utoa(a.b))
- if s != a.s {
- t.Errorf("string%+v\n\tgot s = %s; want %s", a, s, a.s)
- }
-
- x, b, _, err := nat(nil).scan(strings.NewReader(a.s), a.b, false)
- if x.cmp(a.x) != 0 {
- t.Errorf("scan%+v\n\tgot z = %v; want %v", a, x, a.x)
- }
- if b != a.b {
- t.Errorf("scan%+v\n\tgot b = %d; want %d", a, b, a.b)
- }
- if err != nil {
- t.Errorf("scan%+v\n\tgot error = %s", a, err)
- }
- }
-}
-
-var natScanTests = []struct {
- s string // string to be scanned
- base int // input base
- frac bool // fraction ok
- x nat // expected nat
- b int // expected base
- count int // expected digit count
- ok bool // expected success
- next rune // next character (or 0, if at EOF)
-}{
- // error: no mantissa
- {},
- {s: "?"},
- {base: 10},
- {base: 36},
- {s: "?", base: 10},
- {s: "0x"},
- {s: "345", base: 2},
-
- // error: incorrect use of decimal point
- {s: ".0"},
- {s: ".0", base: 10},
- {s: ".", base: 0},
- {s: "0x.0"},
-
- // no errors
- {"0", 0, false, nil, 10, 1, true, 0},
- {"0", 10, false, nil, 10, 1, true, 0},
- {"0", 36, false, nil, 36, 1, true, 0},
- {"1", 0, false, nat{1}, 10, 1, true, 0},
- {"1", 10, false, nat{1}, 10, 1, true, 0},
- {"0 ", 0, false, nil, 10, 1, true, ' '},
- {"08", 0, false, nil, 10, 1, true, '8'},
- {"08", 10, false, nat{8}, 10, 2, true, 0},
- {"018", 0, false, nat{1}, 8, 1, true, '8'},
- {"0b1", 0, false, nat{1}, 2, 1, true, 0},
- {"0b11000101", 0, false, nat{0xc5}, 2, 8, true, 0},
- {"03271", 0, false, nat{03271}, 8, 4, true, 0},
- {"10ab", 0, false, nat{10}, 10, 2, true, 'a'},
- {"1234567890", 0, false, nat{1234567890}, 10, 10, true, 0},
- {"xyz", 36, false, nat{(33*36+34)*36 + 35}, 36, 3, true, 0},
- {"xyz?", 36, false, nat{(33*36+34)*36 + 35}, 36, 3, true, '?'},
- {"0x", 16, false, nil, 16, 1, true, 'x'},
- {"0xdeadbeef", 0, false, nat{0xdeadbeef}, 16, 8, true, 0},
- {"0XDEADBEEF", 0, false, nat{0xdeadbeef}, 16, 8, true, 0},
-
- // no errors, decimal point
- {"0.", 0, false, nil, 10, 1, true, '.'},
- {"0.", 10, true, nil, 10, 0, true, 0},
- {"0.1.2", 10, true, nat{1}, 10, -1, true, '.'},
- {".000", 10, true, nil, 10, -3, true, 0},
- {"12.3", 10, true, nat{123}, 10, -1, true, 0},
- {"012.345", 10, true, nat{12345}, 10, -3, true, 0},
-}
-
-func TestScanBase(t *testing.T) {
- for _, a := range natScanTests {
- r := strings.NewReader(a.s)
- x, b, count, err := nat(nil).scan(r, a.base, a.frac)
- if err == nil && !a.ok {
- t.Errorf("scan%+v\n\texpected error", a)
- }
- if err != nil {
- if a.ok {
- t.Errorf("scan%+v\n\tgot error = %s", a, err)
- }
- continue
- }
- if x.cmp(a.x) != 0 {
- t.Errorf("scan%+v\n\tgot z = %v; want %v", a, x, a.x)
- }
- if b != a.b {
- t.Errorf("scan%+v\n\tgot b = %d; want %d", a, b, a.base)
- }
- if count != a.count {
- t.Errorf("scan%+v\n\tgot count = %d; want %d", a, count, a.count)
- }
- next, _, err := r.ReadRune()
- if err == io.EOF {
- next = 0
- err = nil
- }
- if err == nil && next != a.next {
- t.Errorf("scan%+v\n\tgot next = %q; want %q", a, next, a.next)
- }
- }
-}
-
-var pi = "3" +
- "14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651" +
- "32823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461" +
- "28475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920" +
- "96282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179" +
- "31051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798" +
- "60943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901" +
- "22495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837" +
- "29780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083" +
- "81420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909" +
- "21642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151" +
- "55748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035" +
- "63707660104710181942955596198946767837449448255379774726847104047534646208046684259069491293313677028989152104" +
- "75216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992" +
- "45863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818" +
- "34797753566369807426542527862551818417574672890977772793800081647060016145249192173217214772350141441973568548" +
- "16136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179" +
- "04946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886" +
- "26945604241965285022210661186306744278622039194945047123713786960956364371917287467764657573962413890865832645" +
- "99581339047802759009946576407895126946839835259570982582262052248940772671947826848260147699090264013639443745" +
- "53050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382" +
- "68683868942774155991855925245953959431049972524680845987273644695848653836736222626099124608051243884390451244" +
- "13654976278079771569143599770012961608944169486855584840635342207222582848864815845602850601684273945226746767" +
- "88952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288" +
- "79710893145669136867228748940560101503308617928680920874760917824938589009714909675985261365549781893129784821" +
- "68299894872265880485756401427047755513237964145152374623436454285844479526586782105114135473573952311342716610" +
- "21359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435" +
- "06430218453191048481005370614680674919278191197939952061419663428754440643745123718192179998391015919561814675" +
- "14269123974894090718649423196156794520809514655022523160388193014209376213785595663893778708303906979207734672" +
- "21825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539" +
- "05796268561005508106658796998163574736384052571459102897064140110971206280439039759515677157700420337869936007" +
- "23055876317635942187312514712053292819182618612586732157919841484882916447060957527069572209175671167229109816" +
- "90915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398" +
- "31501970165151168517143765761835155650884909989859982387345528331635507647918535893226185489632132933089857064" +
- "20467525907091548141654985946163718027098199430992448895757128289059232332609729971208443357326548938239119325" +
- "97463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100" +
- "44929321516084244485963766983895228684783123552658213144957685726243344189303968642624341077322697802807318915" +
- "44110104468232527162010526522721116603966655730925471105578537634668206531098965269186205647693125705863566201" +
- "85581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318" +
- "58676975145661406800700237877659134401712749470420562230538994561314071127000407854733269939081454664645880797" +
- "27082668306343285878569830523580893306575740679545716377525420211495576158140025012622859413021647155097925923" +
- "09907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111" +
- "79042978285647503203198691514028708085990480109412147221317947647772622414254854540332157185306142288137585043" +
- "06332175182979866223717215916077166925474873898665494945011465406284336639379003976926567214638530673609657120" +
- "91807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862" +
- "94726547364252308177036751590673502350728354056704038674351362222477158915049530984448933309634087807693259939" +
- "78054193414473774418426312986080998886874132604721569516239658645730216315981931951673538129741677294786724229" +
- "24654366800980676928238280689964004824354037014163149658979409243237896907069779422362508221688957383798623001" +
- "59377647165122893578601588161755782973523344604281512627203734314653197777416031990665541876397929334419521541" +
- "34189948544473456738316249934191318148092777710386387734317720754565453220777092120190516609628049092636019759" +
- "88281613323166636528619326686336062735676303544776280350450777235547105859548702790814356240145171806246436267" +
- "94561275318134078330336254232783944975382437205835311477119926063813346776879695970309833913077109870408591337"
-
-// Test case for BenchmarkScanPi.
-func TestScanPi(t *testing.T) {
- var x nat
- z, _, _, err := x.scan(strings.NewReader(pi), 10, false)
- if err != nil {
- t.Errorf("scanning pi: %s", err)
- }
- if s := string(z.utoa(10)); s != pi {
- t.Errorf("scanning pi: got %s", s)
- }
-}
-
-func TestScanPiParallel(t *testing.T) {
- const n = 2
- c := make(chan int)
- for i := 0; i < n; i++ {
- go func() {
- TestScanPi(t)
- c <- 0
- }()
- }
- for i := 0; i < n; i++ {
- <-c
- }
-}
-
-func BenchmarkScanPi(b *testing.B) {
- for i := 0; i < b.N; i++ {
- var x nat
- x.scan(strings.NewReader(pi), 10, false)
- }
-}
-
-func BenchmarkStringPiParallel(b *testing.B) {
- var x nat
- x, _, _, _ = x.scan(strings.NewReader(pi), 0, false)
- if string(x.utoa(10)) != pi {
- panic("benchmark incorrect: conversion failed")
- }
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- x.utoa(10)
- }
- })
-}
-
-func BenchmarkScan(b *testing.B) {
- const x = 10
- for _, base := range []int{2, 8, 10, 16} {
- for _, y := range []Word{10, 100, 1000, 10000, 100000} {
- b.Run(fmt.Sprintf("%d/Base%d", y, base), func(b *testing.B) {
- b.StopTimer()
- var z nat
- z = z.expWW(x, y)
-
- s := z.utoa(base)
- if t := itoa(z, base); !bytes.Equal(s, t) {
- b.Fatalf("scanning: got %s; want %s", s, t)
- }
- b.StartTimer()
-
- for i := 0; i < b.N; i++ {
- z.scan(bytes.NewReader(s), base, false)
- }
- })
- }
- }
-}
-
-func BenchmarkString(b *testing.B) {
- const x = 10
- for _, base := range []int{2, 8, 10, 16} {
- for _, y := range []Word{10, 100, 1000, 10000, 100000} {
- b.Run(fmt.Sprintf("%d/Base%d", y, base), func(b *testing.B) {
- b.StopTimer()
- var z nat
- z = z.expWW(x, y)
- z.utoa(base) // warm divisor cache
- b.StartTimer()
-
- for i := 0; i < b.N; i++ {
- _ = z.utoa(base)
- }
- })
- }
- }
-}
-
-func BenchmarkLeafSize(b *testing.B) {
- for n := 0; n <= 16; n++ {
- b.Run(fmt.Sprint(n), func(b *testing.B) { LeafSizeHelper(b, 10, n) })
- }
- // Try some large lengths
- for _, n := range []int{32, 64} {
- b.Run(fmt.Sprint(n), func(b *testing.B) { LeafSizeHelper(b, 10, n) })
- }
-}
-
-func LeafSizeHelper(b *testing.B, base, size int) {
- b.StopTimer()
- originalLeafSize := leafSize
- resetTable(cacheBase10.table[:])
- leafSize = size
- b.StartTimer()
-
- for d := 1; d <= 10000; d *= 10 {
- b.StopTimer()
- var z nat
- z = z.expWW(Word(base), Word(d)) // build target number
- _ = z.utoa(base) // warm divisor cache
- b.StartTimer()
-
- for i := 0; i < b.N; i++ {
- _ = z.utoa(base)
- }
- }
-
- b.StopTimer()
- resetTable(cacheBase10.table[:])
- leafSize = originalLeafSize
- b.StartTimer()
-}
-
-func resetTable(table []divisor) {
- if table != nil && table[0].bbb != nil {
- for i := 0; i < len(table); i++ {
- table[i].bbb = nil
- table[i].nbits = 0
- table[i].ndigits = 0
- }
- }
-}
-
-func TestStringPowers(t *testing.T) {
- var p Word
- for b := 2; b <= 16; b++ {
- for p = 0; p <= 512; p++ {
- x := nat(nil).expWW(Word(b), p)
- xs := x.utoa(b)
- xs2 := itoa(x, b)
- if !bytes.Equal(xs, xs2) {
- t.Errorf("failed at %d ** %d in base %d: %s != %s", b, p, b, xs, xs2)
- }
- }
- if b >= 3 && testing.Short() {
- break
- }
- }
-}
diff --git a/src/cmd/compile/internal/big/rat.go b/src/cmd/compile/internal/big/rat.go
deleted file mode 100644
index 56ce33d..0000000
--- a/src/cmd/compile/internal/big/rat.go
+++ /dev/null
@@ -1,510 +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.
-
-// This file implements multi-precision rational numbers.
-
-package big
-
-import (
- "fmt"
- "math"
-)
-
-// A Rat represents a quotient a/b of arbitrary precision.
-// The zero value for a Rat represents the value 0.
-type Rat struct {
- // To make zero values for Rat work w/o initialization,
- // a zero value of b (len(b) == 0) acts like b == 1.
- // a.neg determines the sign of the Rat, b.neg is ignored.
- a, b Int
-}
-
-// NewRat creates a new Rat with numerator a and denominator b.
-func NewRat(a, b int64) *Rat {
- return new(Rat).SetFrac64(a, b)
-}
-
-// SetFloat64 sets z to exactly f and returns z.
-// If f is not finite, SetFloat returns nil.
-func (z *Rat) SetFloat64(f float64) *Rat {
- const expMask = 1<<11 - 1
- bits := math.Float64bits(f)
- mantissa := bits & (1<<52 - 1)
- exp := int((bits >> 52) & expMask)
- switch exp {
- case expMask: // non-finite
- return nil
- case 0: // denormal
- exp -= 1022
- default: // normal
- mantissa |= 1 << 52
- exp -= 1023
- }
-
- shift := 52 - exp
-
- // Optimization (?): partially pre-normalise.
- for mantissa&1 == 0 && shift > 0 {
- mantissa >>= 1
- shift--
- }
-
- z.a.SetUint64(mantissa)
- z.a.neg = f < 0
- z.b.Set(intOne)
- if shift > 0 {
- z.b.Lsh(&z.b, uint(shift))
- } else {
- z.a.Lsh(&z.a, uint(-shift))
- }
- return z.norm()
-}
-
-// quotToFloat32 returns the non-negative float32 value
-// nearest to the quotient a/b, using round-to-even in
-// halfway cases. It does not mutate its arguments.
-// Preconditions: b is non-zero; a and b have no common factors.
-func quotToFloat32(a, b nat) (f float32, exact bool) {
- const (
- // float size in bits
- Fsize = 32
-
- // mantissa
- Msize = 23
- Msize1 = Msize + 1 // incl. implicit 1
- Msize2 = Msize1 + 1
-
- // exponent
- Esize = Fsize - Msize1
- Ebias = 1<<(Esize-1) - 1
- Emin = 1 - Ebias
- Emax = Ebias
- )
-
- // TODO(adonovan): specialize common degenerate cases: 1.0, integers.
- alen := a.bitLen()
- if alen == 0 {
- return 0, true
- }
- blen := b.bitLen()
- if blen == 0 {
- panic("division by zero")
- }
-
- // 1. Left-shift A or B such that quotient A/B is in [1<<Msize1, 1<<(Msize2+1)
- // (Msize2 bits if A < B when they are left-aligned, Msize2+1 bits if A >= B).
- // This is 2 or 3 more than the float32 mantissa field width of Msize:
- // - the optional extra bit is shifted away in step 3 below.
- // - the high-order 1 is omitted in "normal" representation;
- // - the low-order 1 will be used during rounding then discarded.
- exp := alen - blen
- var a2, b2 nat
- a2 = a2.set(a)
- b2 = b2.set(b)
- if shift := Msize2 - exp; shift > 0 {
- a2 = a2.shl(a2, uint(shift))
- } else if shift < 0 {
- b2 = b2.shl(b2, uint(-shift))
- }
-
- // 2. Compute quotient and remainder (q, r). NB: due to the
- // extra shift, the low-order bit of q is logically the
- // high-order bit of r.
- var q nat
- q, r := q.div(a2, a2, b2) // (recycle a2)
- mantissa := low32(q)
- haveRem := len(r) > 0 // mantissa&1 && !haveRem => remainder is exactly half
-
- // 3. If quotient didn't fit in Msize2 bits, redo division by b2<<1
- // (in effect---we accomplish this incrementally).
- if mantissa>>Msize2 == 1 {
- if mantissa&1 == 1 {
- haveRem = true
- }
- mantissa >>= 1
- exp++
- }
- if mantissa>>Msize1 != 1 {
- panic(fmt.Sprintf("expected exactly %d bits of result", Msize2))
- }
-
- // 4. Rounding.
- if Emin-Msize <= exp && exp <= Emin {
- // Denormal case; lose 'shift' bits of precision.
- shift := uint(Emin - (exp - 1)) // [1..Esize1)
- lostbits := mantissa & (1<<shift - 1)
- haveRem = haveRem || lostbits != 0
- mantissa >>= shift
- exp = 2 - Ebias // == exp + shift
- }
- // Round q using round-half-to-even.
- exact = !haveRem
- if mantissa&1 != 0 {
- exact = false
- if haveRem || mantissa&2 != 0 {
- if mantissa++; mantissa >= 1<<Msize2 {
- // Complete rollover 11...1 => 100...0, so shift is safe
- mantissa >>= 1
- exp++
- }
- }
- }
- mantissa >>= 1 // discard rounding bit. Mantissa now scaled by 1<<Msize1.
-
- f = float32(math.Ldexp(float64(mantissa), exp-Msize1))
- if math.IsInf(float64(f), 0) {
- exact = false
- }
- return
-}
-
-// quotToFloat64 returns the non-negative float64 value
-// nearest to the quotient a/b, using round-to-even in
-// halfway cases. It does not mutate its arguments.
-// Preconditions: b is non-zero; a and b have no common factors.
-func quotToFloat64(a, b nat) (f float64, exact bool) {
- const (
- // float size in bits
- Fsize = 64
-
- // mantissa
- Msize = 52
- Msize1 = Msize + 1 // incl. implicit 1
- Msize2 = Msize1 + 1
-
- // exponent
- Esize = Fsize - Msize1
- Ebias = 1<<(Esize-1) - 1
- Emin = 1 - Ebias
- Emax = Ebias
- )
-
- // TODO(adonovan): specialize common degenerate cases: 1.0, integers.
- alen := a.bitLen()
- if alen == 0 {
- return 0, true
- }
- blen := b.bitLen()
- if blen == 0 {
- panic("division by zero")
- }
-
- // 1. Left-shift A or B such that quotient A/B is in [1<<Msize1, 1<<(Msize2+1)
- // (Msize2 bits if A < B when they are left-aligned, Msize2+1 bits if A >= B).
- // This is 2 or 3 more than the float64 mantissa field width of Msize:
- // - the optional extra bit is shifted away in step 3 below.
- // - the high-order 1 is omitted in "normal" representation;
- // - the low-order 1 will be used during rounding then discarded.
- exp := alen - blen
- var a2, b2 nat
- a2 = a2.set(a)
- b2 = b2.set(b)
- if shift := Msize2 - exp; shift > 0 {
- a2 = a2.shl(a2, uint(shift))
- } else if shift < 0 {
- b2 = b2.shl(b2, uint(-shift))
- }
-
- // 2. Compute quotient and remainder (q, r). NB: due to the
- // extra shift, the low-order bit of q is logically the
- // high-order bit of r.
- var q nat
- q, r := q.div(a2, a2, b2) // (recycle a2)
- mantissa := low64(q)
- haveRem := len(r) > 0 // mantissa&1 && !haveRem => remainder is exactly half
-
- // 3. If quotient didn't fit in Msize2 bits, redo division by b2<<1
- // (in effect---we accomplish this incrementally).
- if mantissa>>Msize2 == 1 {
- if mantissa&1 == 1 {
- haveRem = true
- }
- mantissa >>= 1
- exp++
- }
- if mantissa>>Msize1 != 1 {
- panic(fmt.Sprintf("expected exactly %d bits of result", Msize2))
- }
-
- // 4. Rounding.
- if Emin-Msize <= exp && exp <= Emin {
- // Denormal case; lose 'shift' bits of precision.
- shift := uint(Emin - (exp - 1)) // [1..Esize1)
- lostbits := mantissa & (1<<shift - 1)
- haveRem = haveRem || lostbits != 0
- mantissa >>= shift
- exp = 2 - Ebias // == exp + shift
- }
- // Round q using round-half-to-even.
- exact = !haveRem
- if mantissa&1 != 0 {
- exact = false
- if haveRem || mantissa&2 != 0 {
- if mantissa++; mantissa >= 1<<Msize2 {
- // Complete rollover 11...1 => 100...0, so shift is safe
- mantissa >>= 1
- exp++
- }
- }
- }
- mantissa >>= 1 // discard rounding bit. Mantissa now scaled by 1<<Msize1.
-
- f = math.Ldexp(float64(mantissa), exp-Msize1)
- if math.IsInf(f, 0) {
- exact = false
- }
- return
-}
-
-// Float32 returns the nearest float32 value for x and a bool indicating
-// whether f represents x exactly. If the magnitude of x is too large to
-// be represented by a float32, f is an infinity and exact is false.
-// The sign of f always matches the sign of x, even if f == 0.
-func (x *Rat) Float32() (f float32, exact bool) {
- b := x.b.abs
- if len(b) == 0 {
- b = b.set(natOne) // materialize denominator
- }
- f, exact = quotToFloat32(x.a.abs, b)
- if x.a.neg {
- f = -f
- }
- return
-}
-
-// Float64 returns the nearest float64 value for x and a bool indicating
-// whether f represents x exactly. If the magnitude of x is too large to
-// be represented by a float64, f is an infinity and exact is false.
-// The sign of f always matches the sign of x, even if f == 0.
-func (x *Rat) Float64() (f float64, exact bool) {
- b := x.b.abs
- if len(b) == 0 {
- b = b.set(natOne) // materialize denominator
- }
- f, exact = quotToFloat64(x.a.abs, b)
- if x.a.neg {
- f = -f
- }
- return
-}
-
-// SetFrac sets z to a/b and returns z.
-func (z *Rat) SetFrac(a, b *Int) *Rat {
- z.a.neg = a.neg != b.neg
- babs := b.abs
- if len(babs) == 0 {
- panic("division by zero")
- }
- if &z.a == b || alias(z.a.abs, babs) {
- babs = nat(nil).set(babs) // make a copy
- }
- z.a.abs = z.a.abs.set(a.abs)
- z.b.abs = z.b.abs.set(babs)
- return z.norm()
-}
-
-// SetFrac64 sets z to a/b and returns z.
-func (z *Rat) SetFrac64(a, b int64) *Rat {
- z.a.SetInt64(a)
- if b == 0 {
- panic("division by zero")
- }
- if b < 0 {
- b = -b
- z.a.neg = !z.a.neg
- }
- z.b.abs = z.b.abs.setUint64(uint64(b))
- return z.norm()
-}
-
-// SetInt sets z to x (by making a copy of x) and returns z.
-func (z *Rat) SetInt(x *Int) *Rat {
- z.a.Set(x)
- z.b.abs = z.b.abs[:0]
- return z
-}
-
-// SetInt64 sets z to x and returns z.
-func (z *Rat) SetInt64(x int64) *Rat {
- z.a.SetInt64(x)
- z.b.abs = z.b.abs[:0]
- return z
-}
-
-// Set sets z to x (by making a copy of x) and returns z.
-func (z *Rat) Set(x *Rat) *Rat {
- if z != x {
- z.a.Set(&x.a)
- z.b.Set(&x.b)
- }
- return z
-}
-
-// Abs sets z to |x| (the absolute value of x) and returns z.
-func (z *Rat) Abs(x *Rat) *Rat {
- z.Set(x)
- z.a.neg = false
- return z
-}
-
-// Neg sets z to -x and returns z.
-func (z *Rat) Neg(x *Rat) *Rat {
- z.Set(x)
- z.a.neg = len(z.a.abs) > 0 && !z.a.neg // 0 has no sign
- return z
-}
-
-// Inv sets z to 1/x and returns z.
-func (z *Rat) Inv(x *Rat) *Rat {
- if len(x.a.abs) == 0 {
- panic("division by zero")
- }
- z.Set(x)
- a := z.b.abs
- if len(a) == 0 {
- a = a.set(natOne) // materialize numerator
- }
- b := z.a.abs
- if b.cmp(natOne) == 0 {
- b = b[:0] // normalize denominator
- }
- z.a.abs, z.b.abs = a, b // sign doesn't change
- return z
-}
-
-// Sign returns:
-//
-// -1 if x < 0
-// 0 if x == 0
-// +1 if x > 0
-//
-func (x *Rat) Sign() int {
- return x.a.Sign()
-}
-
-// IsInt reports whether the denominator of x is 1.
-func (x *Rat) IsInt() bool {
- return len(x.b.abs) == 0 || x.b.abs.cmp(natOne) == 0
-}
-
-// Num returns the numerator of x; it may be <= 0.
-// The result is a reference to x's numerator; it
-// may change if a new value is assigned to x, and vice versa.
-// The sign of the numerator corresponds to the sign of x.
-func (x *Rat) Num() *Int {
- return &x.a
-}
-
-// Denom returns the denominator of x; it is always > 0.
-// The result is a reference to x's denominator; it
-// may change if a new value is assigned to x, and vice versa.
-func (x *Rat) Denom() *Int {
- x.b.neg = false // the result is always >= 0
- if len(x.b.abs) == 0 {
- x.b.abs = x.b.abs.set(natOne) // materialize denominator
- }
- return &x.b
-}
-
-func (z *Rat) norm() *Rat {
- switch {
- case len(z.a.abs) == 0:
- // z == 0 - normalize sign and denominator
- z.a.neg = false
- z.b.abs = z.b.abs[:0]
- case len(z.b.abs) == 0:
- // z is normalized int - nothing to do
- case z.b.abs.cmp(natOne) == 0:
- // z is int - normalize denominator
- z.b.abs = z.b.abs[:0]
- default:
- neg := z.a.neg
- z.a.neg = false
- z.b.neg = false
- if f := NewInt(0).binaryGCD(&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 {
- // z is int - normalize denominator
- z.b.abs = z.b.abs[:0]
- }
- }
- z.a.neg = neg
- }
- return z
-}
-
-// mulDenom sets z to the denominator product x*y (by taking into
-// account that 0 values for x or y must be interpreted as 1) and
-// returns z.
-func mulDenom(z, x, y nat) nat {
- switch {
- case len(x) == 0:
- return z.set(y)
- case len(y) == 0:
- return z.set(x)
- }
- return z.mul(x, y)
-}
-
-// scaleDenom computes x*f.
-// If f == 0 (zero value of denominator), the result is (a copy of) x.
-func scaleDenom(x *Int, f nat) *Int {
- var z Int
- if len(f) == 0 {
- return z.Set(x)
- }
- z.abs = z.abs.mul(x.abs, f)
- z.neg = x.neg
- return &z
-}
-
-// Cmp compares x and y and returns:
-//
-// -1 if x < y
-// 0 if x == y
-// +1 if x > y
-//
-func (x *Rat) Cmp(y *Rat) int {
- return scaleDenom(&x.a, y.b.abs).Cmp(scaleDenom(&y.a, x.b.abs))
-}
-
-// Add sets z to the sum x+y and returns z.
-func (z *Rat) Add(x, y *Rat) *Rat {
- a1 := scaleDenom(&x.a, y.b.abs)
- a2 := scaleDenom(&y.a, x.b.abs)
- z.a.Add(a1, a2)
- z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
- return z.norm()
-}
-
-// Sub sets z to the difference x-y and returns z.
-func (z *Rat) Sub(x, y *Rat) *Rat {
- a1 := scaleDenom(&x.a, y.b.abs)
- a2 := scaleDenom(&y.a, x.b.abs)
- z.a.Sub(a1, a2)
- z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
- return z.norm()
-}
-
-// Mul sets z to the product x*y and returns z.
-func (z *Rat) Mul(x, y *Rat) *Rat {
- z.a.Mul(&x.a, &y.a)
- z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
- return z.norm()
-}
-
-// Quo sets z to the quotient x/y and returns z.
-// If y == 0, a division-by-zero run-time panic occurs.
-func (z *Rat) Quo(x, y *Rat) *Rat {
- if len(y.a.abs) == 0 {
- panic("division by zero")
- }
- a := scaleDenom(&x.a, y.b.abs)
- b := scaleDenom(&y.a, x.b.abs)
- z.a.abs = a.abs
- z.b.abs = b.abs
- z.a.neg = a.neg != b.neg
- return z.norm()
-}
diff --git a/src/cmd/compile/internal/big/rat_test.go b/src/cmd/compile/internal/big/rat_test.go
deleted file mode 100644
index 3a06fca..0000000
--- a/src/cmd/compile/internal/big/rat_test.go
+++ /dev/null
@@ -1,622 +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 big
-
-import (
- "math"
- "testing"
-)
-
-func TestZeroRat(t *testing.T) {
- var x, y, z Rat
- y.SetFrac64(0, 42)
-
- if x.Cmp(&y) != 0 {
- t.Errorf("x and y should be both equal and zero")
- }
-
- if s := x.String(); s != "0/1" {
- t.Errorf("got x = %s, want 0/1", s)
- }
-
- if s := x.RatString(); s != "0" {
- t.Errorf("got x = %s, want 0", s)
- }
-
- z.Add(&x, &y)
- if s := z.RatString(); s != "0" {
- t.Errorf("got x+y = %s, want 0", s)
- }
-
- z.Sub(&x, &y)
- if s := z.RatString(); s != "0" {
- t.Errorf("got x-y = %s, want 0", s)
- }
-
- z.Mul(&x, &y)
- if s := z.RatString(); s != "0" {
- t.Errorf("got x*y = %s, want 0", s)
- }
-
- // check for division by zero
- defer func() {
- if s := recover(); s == nil || s.(string) != "division by zero" {
- panic(s)
- }
- }()
- z.Quo(&x, &y)
-}
-
-func TestRatSign(t *testing.T) {
- zero := NewRat(0, 1)
- for _, a := range setStringTests {
- x, ok := new(Rat).SetString(a.in)
- if !ok {
- continue
- }
- s := x.Sign()
- e := x.Cmp(zero)
- if s != e {
- t.Errorf("got %d; want %d for z = %v", s, e, &x)
- }
- }
-}
-
-var ratCmpTests = []struct {
- rat1, rat2 string
- out int
-}{
- {"0", "0/1", 0},
- {"1/1", "1", 0},
- {"-1", "-2/2", 0},
- {"1", "0", 1},
- {"0/1", "1/1", -1},
- {"-5/1434770811533343057144", "-5/1434770811533343057145", -1},
- {"49832350382626108453/8964749413", "49832350382626108454/8964749413", -1},
- {"-37414950961700930/7204075375675961", "37414950961700930/7204075375675961", -1},
- {"37414950961700930/7204075375675961", "74829901923401860/14408150751351922", 0},
-}
-
-func TestRatCmp(t *testing.T) {
- for i, test := range ratCmpTests {
- x, _ := new(Rat).SetString(test.rat1)
- y, _ := new(Rat).SetString(test.rat2)
-
- out := x.Cmp(y)
- if out != test.out {
- t.Errorf("#%d got out = %v; want %v", i, out, test.out)
- }
- }
-}
-
-func TestIsInt(t *testing.T) {
- one := NewInt(1)
- for _, a := range setStringTests {
- x, ok := new(Rat).SetString(a.in)
- if !ok {
- continue
- }
- i := x.IsInt()
- e := x.Denom().Cmp(one) == 0
- if i != e {
- t.Errorf("got IsInt(%v) == %v; want %v", x, i, e)
- }
- }
-}
-
-func TestRatAbs(t *testing.T) {
- zero := new(Rat)
- for _, a := range setStringTests {
- x, ok := new(Rat).SetString(a.in)
- if !ok {
- continue
- }
- e := new(Rat).Set(x)
- if e.Cmp(zero) < 0 {
- e.Sub(zero, e)
- }
- z := new(Rat).Abs(x)
- if z.Cmp(e) != 0 {
- t.Errorf("got Abs(%v) = %v; want %v", x, z, e)
- }
- }
-}
-
-func TestRatNeg(t *testing.T) {
- zero := new(Rat)
- for _, a := range setStringTests {
- x, ok := new(Rat).SetString(a.in)
- if !ok {
- continue
- }
- e := new(Rat).Sub(zero, x)
- z := new(Rat).Neg(x)
- if z.Cmp(e) != 0 {
- t.Errorf("got Neg(%v) = %v; want %v", x, z, e)
- }
- }
-}
-
-func TestRatInv(t *testing.T) {
- zero := new(Rat)
- for _, a := range setStringTests {
- x, ok := new(Rat).SetString(a.in)
- if !ok {
- continue
- }
- if x.Cmp(zero) == 0 {
- continue // avoid division by zero
- }
- e := new(Rat).SetFrac(x.Denom(), x.Num())
- z := new(Rat).Inv(x)
- if z.Cmp(e) != 0 {
- t.Errorf("got Inv(%v) = %v; want %v", x, z, e)
- }
- }
-}
-
-type ratBinFun func(z, x, y *Rat) *Rat
-type ratBinArg struct {
- x, y, z string
-}
-
-func testRatBin(t *testing.T, i int, name string, f ratBinFun, a ratBinArg) {
- x, _ := new(Rat).SetString(a.x)
- y, _ := new(Rat).SetString(a.y)
- z, _ := new(Rat).SetString(a.z)
- out := f(new(Rat), x, y)
-
- if out.Cmp(z) != 0 {
- t.Errorf("%s #%d got %s want %s", name, i, out, z)
- }
-}
-
-var ratBinTests = []struct {
- x, y string
- sum, prod string
-}{
- {"0", "0", "0", "0"},
- {"0", "1", "1", "0"},
- {"-1", "0", "-1", "0"},
- {"-1", "1", "0", "-1"},
- {"1", "1", "2", "1"},
- {"1/2", "1/2", "1", "1/4"},
- {"1/4", "1/3", "7/12", "1/12"},
- {"2/5", "-14/3", "-64/15", "-28/15"},
- {"4707/49292519774798173060", "-3367/70976135186689855734", "84058377121001851123459/1749296273614329067191168098769082663020", "-1760941/388732505247628681598037355282018369560"},
- {"-61204110018146728334/3", "-31052192278051565633/2", "-215564796870448153567/6", "950260896245257153059642991192710872711/3"},
- {"-854857841473707320655/4237645934602118692642972629634714039", "-18/31750379913563777419", "-27/133467566250814981", "15387441146526731771790/134546868362786310073779084329032722548987800600710485341"},
- {"618575745270541348005638912139/19198433543745179392300736", "-19948846211000086/637313996471", "27674141753240653/30123979153216", "-6169936206128396568797607742807090270137721977/6117715203873571641674006593837351328"},
- {"-3/26206484091896184128", "5/2848423294177090248", "15310893822118706237/9330894968229805033368778458685147968", "-5/24882386581946146755650075889827061248"},
- {"26946729/330400702820", "41563965/225583428284", "1238218672302860271/4658307703098666660055", "224002580204097/14906584649915733312176"},
- {"-8259900599013409474/7", "-84829337473700364773/56707961321161574960", "-468402123685491748914621885145127724451/396955729248131024720", "350340947706464153265156004876107029701/198477864624065512360"},
- {"575775209696864/1320203974639986246357", "29/712593081308", "410331716733912717985762465/940768218243776489278275419794956", "808/45524274987585732633"},
- {"1786597389946320496771/2066653520653241", "6269770/1992362624741777", "3559549865190272133656109052308126637/4117523232840525481453983149257", "8967230/3296219033"},
- {"-36459180403360509753/32150500941194292113930", "9381566963714/9633539", "301622077145533298008420642898530153/309723104686531919656937098270", "-3784609207827/3426986245"},
-}
-
-func TestRatBin(t *testing.T) {
- for i, test := range ratBinTests {
- arg := ratBinArg{test.x, test.y, test.sum}
- testRatBin(t, i, "Add", (*Rat).Add, arg)
-
- arg = ratBinArg{test.y, test.x, test.sum}
- testRatBin(t, i, "Add symmetric", (*Rat).Add, arg)
-
- arg = ratBinArg{test.sum, test.x, test.y}
- testRatBin(t, i, "Sub", (*Rat).Sub, arg)
-
- arg = ratBinArg{test.sum, test.y, test.x}
- testRatBin(t, i, "Sub symmetric", (*Rat).Sub, arg)
-
- arg = ratBinArg{test.x, test.y, test.prod}
- testRatBin(t, i, "Mul", (*Rat).Mul, arg)
-
- arg = ratBinArg{test.y, test.x, test.prod}
- testRatBin(t, i, "Mul symmetric", (*Rat).Mul, arg)
-
- if test.x != "0" {
- arg = ratBinArg{test.prod, test.x, test.y}
- testRatBin(t, i, "Quo", (*Rat).Quo, arg)
- }
-
- if test.y != "0" {
- arg = ratBinArg{test.prod, test.y, test.x}
- testRatBin(t, i, "Quo symmetric", (*Rat).Quo, arg)
- }
- }
-}
-
-func TestIssue820(t *testing.T) {
- x := NewRat(3, 1)
- y := NewRat(2, 1)
- z := y.Quo(x, y)
- q := NewRat(3, 2)
- if z.Cmp(q) != 0 {
- t.Errorf("got %s want %s", z, q)
- }
-
- y = NewRat(3, 1)
- x = NewRat(2, 1)
- z = y.Quo(x, y)
- q = NewRat(2, 3)
- if z.Cmp(q) != 0 {
- t.Errorf("got %s want %s", z, q)
- }
-
- x = NewRat(3, 1)
- z = x.Quo(x, x)
- q = NewRat(3, 3)
- if z.Cmp(q) != 0 {
- t.Errorf("got %s want %s", z, q)
- }
-}
-
-var setFrac64Tests = []struct {
- a, b int64
- out string
-}{
- {0, 1, "0"},
- {0, -1, "0"},
- {1, 1, "1"},
- {-1, 1, "-1"},
- {1, -1, "-1"},
- {-1, -1, "1"},
- {-9223372036854775808, -9223372036854775808, "1"},
-}
-
-func TestRatSetFrac64Rat(t *testing.T) {
- for i, test := range setFrac64Tests {
- x := new(Rat).SetFrac64(test.a, test.b)
- if x.RatString() != test.out {
- t.Errorf("#%d got %s want %s", i, x.RatString(), test.out)
- }
- }
-}
-
-func TestIssue2379(t *testing.T) {
- // 1) no aliasing
- q := NewRat(3, 2)
- x := new(Rat)
- x.SetFrac(NewInt(3), NewInt(2))
- if x.Cmp(q) != 0 {
- t.Errorf("1) got %s want %s", x, q)
- }
-
- // 2) aliasing of numerator
- x = NewRat(2, 3)
- x.SetFrac(NewInt(3), x.Num())
- if x.Cmp(q) != 0 {
- t.Errorf("2) got %s want %s", x, q)
- }
-
- // 3) aliasing of denominator
- x = NewRat(2, 3)
- x.SetFrac(x.Denom(), NewInt(2))
- if x.Cmp(q) != 0 {
- t.Errorf("3) got %s want %s", x, q)
- }
-
- // 4) aliasing of numerator and denominator
- x = NewRat(2, 3)
- x.SetFrac(x.Denom(), x.Num())
- if x.Cmp(q) != 0 {
- t.Errorf("4) got %s want %s", x, q)
- }
-
- // 5) numerator and denominator are the same
- q = NewRat(1, 1)
- x = new(Rat)
- n := NewInt(7)
- x.SetFrac(n, n)
- if x.Cmp(q) != 0 {
- t.Errorf("5) got %s want %s", x, q)
- }
-}
-
-func TestIssue3521(t *testing.T) {
- a := new(Int)
- b := new(Int)
- a.SetString("64375784358435883458348587", 0)
- b.SetString("4789759874531", 0)
-
- // 0) a raw zero value has 1 as denominator
- zero := new(Rat)
- one := NewInt(1)
- if zero.Denom().Cmp(one) != 0 {
- t.Errorf("0) got %s want %s", zero.Denom(), one)
- }
-
- // 1a) a zero value remains zero independent of denominator
- x := new(Rat)
- x.Denom().Set(new(Int).Neg(b))
- if x.Cmp(zero) != 0 {
- t.Errorf("1a) got %s want %s", x, zero)
- }
-
- // 1b) a zero value may have a denominator != 0 and != 1
- x.Num().Set(a)
- qab := new(Rat).SetFrac(a, b)
- if x.Cmp(qab) != 0 {
- t.Errorf("1b) got %s want %s", x, qab)
- }
-
- // 2a) an integral value becomes a fraction depending on denominator
- x.SetFrac64(10, 2)
- x.Denom().SetInt64(3)
- q53 := NewRat(5, 3)
- if x.Cmp(q53) != 0 {
- t.Errorf("2a) got %s want %s", x, q53)
- }
-
- // 2b) an integral value becomes a fraction depending on denominator
- x = NewRat(10, 2)
- x.Denom().SetInt64(3)
- if x.Cmp(q53) != 0 {
- t.Errorf("2b) got %s want %s", x, q53)
- }
-
- // 3) changing the numerator/denominator of a Rat changes the Rat
- x.SetFrac(a, b)
- a = x.Num()
- b = x.Denom()
- a.SetInt64(5)
- b.SetInt64(3)
- if x.Cmp(q53) != 0 {
- t.Errorf("3) got %s want %s", x, q53)
- }
-}
-
-func TestFloat32Distribution(t *testing.T) {
- // Generate a distribution of (sign, mantissa, exp) values
- // broader than the float32 range, and check Rat.Float32()
- // always picks the closest float32 approximation.
- var add = []int64{
- 0,
- 1,
- 3,
- 5,
- 7,
- 9,
- 11,
- }
- var winc, einc = uint64(1), 1 // soak test (~1.5s on x86-64)
- if testing.Short() {
- winc, einc = 5, 15 // quick test (~60ms on x86-64)
- }
-
- for _, sign := range "+-" {
- for _, a := range add {
- for wid := uint64(0); wid < 30; wid += winc {
- b := 1<<wid + a
- if sign == '-' {
- b = -b
- }
- for exp := -150; exp < 150; exp += einc {
- num, den := NewInt(b), NewInt(1)
- if exp > 0 {
- num.Lsh(num, uint(exp))
- } else {
- den.Lsh(den, uint(-exp))
- }
- r := new(Rat).SetFrac(num, den)
- f, _ := r.Float32()
-
- if !checkIsBestApprox32(t, f, r) {
- // Append context information.
- t.Errorf("(input was mantissa %#x, exp %d; f = %g (%b); f ~ %g; r = %v)",
- b, exp, f, f, math.Ldexp(float64(b), exp), r)
- }
-
- checkNonLossyRoundtrip32(t, f)
- }
- }
- }
- }
-}
-
-func TestFloat64Distribution(t *testing.T) {
- // Generate a distribution of (sign, mantissa, exp) values
- // broader than the float64 range, and check Rat.Float64()
- // always picks the closest float64 approximation.
- var add = []int64{
- 0,
- 1,
- 3,
- 5,
- 7,
- 9,
- 11,
- }
- var winc, einc = uint64(1), 1 // soak test (~75s on x86-64)
- if testing.Short() {
- winc, einc = 10, 500 // quick test (~12ms on x86-64)
- }
-
- for _, sign := range "+-" {
- for _, a := range add {
- for wid := uint64(0); wid < 60; wid += winc {
- b := 1<<wid + a
- if sign == '-' {
- b = -b
- }
- for exp := -1100; exp < 1100; exp += einc {
- num, den := NewInt(b), NewInt(1)
- if exp > 0 {
- num.Lsh(num, uint(exp))
- } else {
- den.Lsh(den, uint(-exp))
- }
- r := new(Rat).SetFrac(num, den)
- f, _ := r.Float64()
-
- if !checkIsBestApprox64(t, f, r) {
- // Append context information.
- t.Errorf("(input was mantissa %#x, exp %d; f = %g (%b); f ~ %g; r = %v)",
- b, exp, f, f, math.Ldexp(float64(b), exp), r)
- }
-
- checkNonLossyRoundtrip64(t, f)
- }
- }
- }
- }
-}
-
-// TestSetFloat64NonFinite checks that SetFloat64 of a non-finite value
-// returns nil.
-func TestSetFloat64NonFinite(t *testing.T) {
- for _, f := range []float64{math.NaN(), math.Inf(+1), math.Inf(-1)} {
- var r Rat
- if r2 := r.SetFloat64(f); r2 != nil {
- t.Errorf("SetFloat64(%g) was %v, want nil", f, r2)
- }
- }
-}
-
-// checkNonLossyRoundtrip32 checks that a float->Rat->float roundtrip is
-// non-lossy for finite f.
-func checkNonLossyRoundtrip32(t *testing.T, f float32) {
- if !isFinite(float64(f)) {
- return
- }
- r := new(Rat).SetFloat64(float64(f))
- if r == nil {
- t.Errorf("Rat.SetFloat64(float64(%g) (%b)) == nil", f, f)
- return
- }
- f2, exact := r.Float32()
- if f != f2 || !exact {
- t.Errorf("Rat.SetFloat64(float64(%g)).Float32() = %g (%b), %v, want %g (%b), %v; delta = %b",
- f, f2, f2, exact, f, f, true, f2-f)
- }
-}
-
-// checkNonLossyRoundtrip64 checks that a float->Rat->float roundtrip is
-// non-lossy for finite f.
-func checkNonLossyRoundtrip64(t *testing.T, f float64) {
- if !isFinite(f) {
- return
- }
- r := new(Rat).SetFloat64(f)
- if r == nil {
- t.Errorf("Rat.SetFloat64(%g (%b)) == nil", f, f)
- return
- }
- f2, exact := r.Float64()
- if f != f2 || !exact {
- t.Errorf("Rat.SetFloat64(%g).Float64() = %g (%b), %v, want %g (%b), %v; delta = %b",
- f, f2, f2, exact, f, f, true, f2-f)
- }
-}
-
-// delta returns the absolute difference between r and f.
-func delta(r *Rat, f float64) *Rat {
- d := new(Rat).Sub(r, new(Rat).SetFloat64(f))
- return d.Abs(d)
-}
-
-// checkIsBestApprox32 checks that f is the best possible float32
-// approximation of r.
-// Returns true on success.
-func checkIsBestApprox32(t *testing.T, f float32, r *Rat) bool {
- if math.Abs(float64(f)) >= math.MaxFloat32 {
- // Cannot check +Inf, -Inf, nor the float next to them (MaxFloat32).
- // But we have tests for these special cases.
- return true
- }
-
- // r must be strictly between f0 and f1, the floats bracketing f.
- f0 := math.Nextafter32(f, float32(math.Inf(-1)))
- f1 := math.Nextafter32(f, float32(math.Inf(+1)))
-
- // For f to be correct, r must be closer to f than to f0 or f1.
- df := delta(r, float64(f))
- df0 := delta(r, float64(f0))
- df1 := delta(r, float64(f1))
- if df.Cmp(df0) > 0 {
- t.Errorf("Rat(%v).Float32() = %g (%b), but previous float32 %g (%b) is closer", r, f, f, f0, f0)
- return false
- }
- if df.Cmp(df1) > 0 {
- t.Errorf("Rat(%v).Float32() = %g (%b), but next float32 %g (%b) is closer", r, f, f, f1, f1)
- return false
- }
- if df.Cmp(df0) == 0 && !isEven32(f) {
- t.Errorf("Rat(%v).Float32() = %g (%b); halfway should have rounded to %g (%b) instead", r, f, f, f0, f0)
- return false
- }
- if df.Cmp(df1) == 0 && !isEven32(f) {
- t.Errorf("Rat(%v).Float32() = %g (%b); halfway should have rounded to %g (%b) instead", r, f, f, f1, f1)
- return false
- }
- return true
-}
-
-// checkIsBestApprox64 checks that f is the best possible float64
-// approximation of r.
-// Returns true on success.
-func checkIsBestApprox64(t *testing.T, f float64, r *Rat) bool {
- if math.Abs(f) >= math.MaxFloat64 {
- // Cannot check +Inf, -Inf, nor the float next to them (MaxFloat64).
- // But we have tests for these special cases.
- return true
- }
-
- // r must be strictly between f0 and f1, the floats bracketing f.
- f0 := math.Nextafter(f, math.Inf(-1))
- f1 := math.Nextafter(f, math.Inf(+1))
-
- // For f to be correct, r must be closer to f than to f0 or f1.
- df := delta(r, f)
- df0 := delta(r, f0)
- df1 := delta(r, f1)
- if df.Cmp(df0) > 0 {
- t.Errorf("Rat(%v).Float64() = %g (%b), but previous float64 %g (%b) is closer", r, f, f, f0, f0)
- return false
- }
- if df.Cmp(df1) > 0 {
- t.Errorf("Rat(%v).Float64() = %g (%b), but next float64 %g (%b) is closer", r, f, f, f1, f1)
- return false
- }
- if df.Cmp(df0) == 0 && !isEven64(f) {
- t.Errorf("Rat(%v).Float64() = %g (%b); halfway should have rounded to %g (%b) instead", r, f, f, f0, f0)
- return false
- }
- if df.Cmp(df1) == 0 && !isEven64(f) {
- t.Errorf("Rat(%v).Float64() = %g (%b); halfway should have rounded to %g (%b) instead", r, f, f, f1, f1)
- return false
- }
- return true
-}
-
-func isEven32(f float32) bool { return math.Float32bits(f)&1 == 0 }
-func isEven64(f float64) bool { return math.Float64bits(f)&1 == 0 }
-
-func TestIsFinite(t *testing.T) {
- finites := []float64{
- 1.0 / 3,
- 4891559871276714924261e+222,
- math.MaxFloat64,
- math.SmallestNonzeroFloat64,
- -math.MaxFloat64,
- -math.SmallestNonzeroFloat64,
- }
- for _, f := range finites {
- if !isFinite(f) {
- t.Errorf("!IsFinite(%g (%b))", f, f)
- }
- }
- nonfinites := []float64{
- math.NaN(),
- math.Inf(-1),
- math.Inf(+1),
- }
- for _, f := range nonfinites {
- if isFinite(f) {
- t.Errorf("IsFinite(%g, (%b))", f, f)
- }
- }
-}
diff --git a/src/cmd/compile/internal/big/ratconv.go b/src/cmd/compile/internal/big/ratconv.go
deleted file mode 100644
index ef2b675..0000000
--- a/src/cmd/compile/internal/big/ratconv.go
+++ /dev/null
@@ -1,270 +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.
-
-// This file implements rat-to-string conversion functions.
-
-package big
-
-import (
- "errors"
- "fmt"
- "io"
- "strconv"
- "strings"
-)
-
-func ratTok(ch rune) bool {
- return strings.ContainsRune("+-/0123456789.eE", ch)
-}
-
-// Scan is a support routine for fmt.Scanner. It accepts the formats
-// 'e', 'E', 'f', 'F', 'g', 'G', and 'v'. All formats are equivalent.
-func (z *Rat) Scan(s fmt.ScanState, ch rune) error {
- tok, err := s.Token(true, ratTok)
- if err != nil {
- return err
- }
- if !strings.ContainsRune("efgEFGv", ch) {
- return errors.New("Rat.Scan: invalid verb")
- }
- if _, ok := z.SetString(string(tok)); !ok {
- return errors.New("Rat.Scan: invalid syntax")
- }
- return nil
-}
-
-// SetString sets z to the value of s and returns z and a boolean indicating
-// success. s can be given as a fraction "a/b" or as a floating-point number
-// optionally followed by an exponent. If the operation failed, the value of
-// z is undefined but the returned value is nil.
-func (z *Rat) SetString(s string) (*Rat, bool) {
- if len(s) == 0 {
- return nil, false
- }
- // len(s) > 0
-
- // parse fraction a/b, if any
- if sep := strings.Index(s, "/"); sep >= 0 {
- if _, ok := z.a.SetString(s[:sep], 0); !ok {
- return nil, false
- }
- s = s[sep+1:]
- var err error
- if z.b.abs, _, _, err = z.b.abs.scan(strings.NewReader(s), 0, false); err != nil {
- return nil, false
- }
- if len(z.b.abs) == 0 {
- return nil, false
- }
- return z.norm(), true
- }
-
- // parse floating-point number
- r := strings.NewReader(s)
-
- // sign
- neg, err := scanSign(r)
- if err != nil {
- return nil, false
- }
-
- // mantissa
- var ecorr int
- z.a.abs, _, ecorr, err = z.a.abs.scan(r, 10, true)
- if err != nil {
- return nil, false
- }
-
- // exponent
- var exp int64
- exp, _, err = scanExponent(r, false)
- if err != nil {
- return nil, false
- }
-
- // there should be no unread characters left
- if _, err = r.ReadByte(); err != io.EOF {
- return nil, false
- }
-
- // special-case 0 (see also issue #16176)
- if len(z.a.abs) == 0 {
- return z, true
- }
- // len(z.a.abs) > 0
-
- // correct exponent
- if ecorr < 0 {
- exp += int64(ecorr)
- }
-
- // compute exponent power
- expabs := exp
- if expabs < 0 {
- expabs = -expabs
- }
- powTen := nat(nil).expNN(natTen, nat(nil).setWord(Word(expabs)), nil)
-
- // complete fraction
- if exp < 0 {
- z.b.abs = powTen
- z.norm()
- } else {
- z.a.abs = z.a.abs.mul(z.a.abs, powTen)
- z.b.abs = z.b.abs[:0]
- }
-
- z.a.neg = neg && len(z.a.abs) > 0 // 0 has no sign
-
- return z, true
-}
-
-// scanExponent scans the longest possible prefix of r representing a decimal
-// ('e', 'E') or binary ('p') exponent, if any. It returns the exponent, the
-// exponent base (10 or 2), or a read or syntax error, if any.
-//
-// exponent = ( "E" | "e" | "p" ) [ sign ] digits .
-// sign = "+" | "-" .
-// digits = digit { digit } .
-// digit = "0" ... "9" .
-//
-// A binary exponent is only permitted if binExpOk is set.
-func scanExponent(r io.ByteScanner, binExpOk bool) (exp int64, base int, err error) {
- base = 10
-
- var ch byte
- if ch, err = r.ReadByte(); err != nil {
- if err == io.EOF {
- err = nil // no exponent; same as e0
- }
- return
- }
-
- switch ch {
- case 'e', 'E':
- // ok
- case 'p':
- if binExpOk {
- base = 2
- break // ok
- }
- fallthrough // binary exponent not permitted
- default:
- r.UnreadByte()
- return // no exponent; same as e0
- }
-
- var neg bool
- if neg, err = scanSign(r); err != nil {
- return
- }
-
- var digits []byte
- if neg {
- digits = append(digits, '-')
- }
-
- // no need to use nat.scan for exponent digits
- // since we only care about int64 values - the
- // from-scratch scan is easy enough and faster
- for i := 0; ; i++ {
- if ch, err = r.ReadByte(); err != nil {
- if err != io.EOF || i == 0 {
- return
- }
- err = nil
- break // i > 0
- }
- if ch < '0' || '9' < ch {
- if i == 0 {
- r.UnreadByte()
- err = fmt.Errorf("invalid exponent (missing digits)")
- return
- }
- break // i > 0
- }
- digits = append(digits, ch)
- }
- // i > 0 => we have at least one digit
-
- exp, err = strconv.ParseInt(string(digits), 10, 64)
- return
-}
-
-// String returns a string representation of x in the form "a/b" (even if b == 1).
-func (x *Rat) String() string {
- var buf []byte
- buf = x.a.Append(buf, 10)
- buf = append(buf, '/')
- if len(x.b.abs) != 0 {
- buf = x.b.Append(buf, 10)
- } else {
- buf = append(buf, '1')
- }
- return string(buf)
-}
-
-// RatString returns a string representation of x in the form "a/b" if b != 1,
-// and in the form "a" if b == 1.
-func (x *Rat) RatString() string {
- if x.IsInt() {
- return x.a.String()
- }
- return x.String()
-}
-
-// FloatString returns a string representation of x in decimal form with prec
-// digits of precision after the decimal point. The last digit is rounded to
-// nearest, with halves rounded away from zero.
-func (x *Rat) FloatString(prec int) string {
- var buf []byte
-
- if x.IsInt() {
- buf = x.a.Append(buf, 10)
- if prec > 0 {
- buf = append(buf, '.')
- for i := prec; i > 0; i-- {
- buf = append(buf, '0')
- }
- }
- return string(buf)
- }
- // x.b.abs != 0
-
- q, r := nat(nil).div(nat(nil), x.a.abs, x.b.abs)
-
- p := natOne
- if prec > 0 {
- p = nat(nil).expNN(natTen, nat(nil).setUint64(uint64(prec)), nil)
- }
-
- r = r.mul(r, p)
- r, r2 := r.div(nat(nil), r, x.b.abs)
-
- // see if we need to round up
- r2 = r2.add(r2, r2)
- if x.b.abs.cmp(r2) <= 0 {
- r = r.add(r, natOne)
- if r.cmp(p) >= 0 {
- q = nat(nil).add(q, natOne)
- r = nat(nil).sub(r, p)
- }
- }
-
- if x.a.neg {
- buf = append(buf, '-')
- }
- buf = append(buf, q.utoa(10)...) // itoa ignores sign if q == 0
-
- if prec > 0 {
- buf = append(buf, '.')
- rs := r.utoa(10)
- for i := prec - len(rs); i > 0; i-- {
- buf = append(buf, '0')
- }
- buf = append(buf, rs...)
- }
-
- return string(buf)
-}
diff --git a/src/cmd/compile/internal/big/ratconv_test.go b/src/cmd/compile/internal/big/ratconv_test.go
deleted file mode 100644
index 35ad6cc..0000000
--- a/src/cmd/compile/internal/big/ratconv_test.go
+++ /dev/null
@@ -1,454 +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.
-
-package big
-
-import (
- "bytes"
- "fmt"
- "math"
- "strconv"
- "strings"
- "testing"
-)
-
-type StringTest struct {
- in, out string
- ok bool
-}
-
-var setStringTests = []StringTest{
- {"0", "0", true},
- {"-0", "0", true},
- {"1", "1", true},
- {"-1", "-1", true},
- {"1.", "1", true},
- {"1e0", "1", true},
- {"1.e1", "10", true},
- {in: "1e"},
- {in: "1.e"},
- {in: "1e+14e-5"},
- {in: "1e4.5"},
- {in: "r"},
- {in: "a/b"},
- {in: "a.b"},
- {"-0.1", "-1/10", true},
- {"-.1", "-1/10", true},
- {"2/4", "1/2", true},
- {".25", "1/4", true},
- {"-1/5", "-1/5", true},
- {"8129567.7690E14", "812956776900000000000", true},
- {"78189e+4", "781890000", true},
- {"553019.8935e+8", "55301989350000", true},
- {"98765432109876543210987654321e-10", "98765432109876543210987654321/10000000000", true},
- {"9877861857500000E-7", "3951144743/4", true},
- {"2169378.417e-3", "2169378417/1000000", true},
- {"884243222337379604041632732738665534", "884243222337379604041632732738665534", true},
- {"53/70893980658822810696", "53/70893980658822810696", true},
- {"106/141787961317645621392", "53/70893980658822810696", true},
- {"204211327800791583.81095", "4084226556015831676219/20000", true},
- {"0e9999999999", "0", true}, // issue #16176
- {in: "1/0"},
-}
-
-// These are not supported by fmt.Fscanf.
-var setStringTests2 = []StringTest{
- {"0x10", "16", true},
- {"-010/1", "-8", true}, // TODO(gri) should we even permit octal here?
- {"-010.", "-10", true},
- {"0x10/0x20", "1/2", true},
- {"0b1000/3", "8/3", true},
- // TODO(gri) add more tests
-}
-
-func TestRatSetString(t *testing.T) {
- var tests []StringTest
- tests = append(tests, setStringTests...)
- tests = append(tests, setStringTests2...)
-
- for i, test := range tests {
- x, ok := new(Rat).SetString(test.in)
-
- if ok {
- if !test.ok {
- t.Errorf("#%d SetString(%q) expected failure", i, test.in)
- } else if x.RatString() != test.out {
- t.Errorf("#%d SetString(%q) got %s want %s", i, test.in, x.RatString(), test.out)
- }
- } else if x != nil {
- t.Errorf("#%d SetString(%q) got %p want nil", i, test.in, x)
- }
- }
-}
-
-func TestRatScan(t *testing.T) {
- var buf bytes.Buffer
- for i, test := range setStringTests {
- x := new(Rat)
- buf.Reset()
- buf.WriteString(test.in)
-
- _, err := fmt.Fscanf(&buf, "%v", x)
- if err == nil != test.ok {
- if test.ok {
- t.Errorf("#%d (%s) error: %s", i, test.in, err)
- } else {
- t.Errorf("#%d (%s) expected error", i, test.in)
- }
- continue
- }
- if err == nil && x.RatString() != test.out {
- t.Errorf("#%d got %s want %s", i, x.RatString(), test.out)
- }
- }
-}
-
-var floatStringTests = []struct {
- in string
- prec int
- out string
-}{
- {"0", 0, "0"},
- {"0", 4, "0.0000"},
- {"1", 0, "1"},
- {"1", 2, "1.00"},
- {"-1", 0, "-1"},
- {"0.05", 1, "0.1"},
- {"-0.05", 1, "-0.1"},
- {".25", 2, "0.25"},
- {".25", 1, "0.3"},
- {".25", 3, "0.250"},
- {"-1/3", 3, "-0.333"},
- {"-2/3", 4, "-0.6667"},
- {"0.96", 1, "1.0"},
- {"0.999", 2, "1.00"},
- {"0.9", 0, "1"},
- {".25", -1, "0"},
- {".55", -1, "1"},
-}
-
-func TestFloatString(t *testing.T) {
- for i, test := range floatStringTests {
- x, _ := new(Rat).SetString(test.in)
-
- if x.FloatString(test.prec) != test.out {
- t.Errorf("#%d got %s want %s", i, x.FloatString(test.prec), test.out)
- }
- }
-}
-
-// Test inputs to Rat.SetString. The prefix "long:" causes the test
-// to be skipped in --test.short mode. (The threshold is about 500us.)
-var float64inputs = []string{
- // Constants plundered from strconv/testfp.txt.
-
- // Table 1: Stress Inputs for Conversion to 53-bit Binary, < 1/2 ULP
- "5e+125",
- "69e+267",
- "999e-026",
- "7861e-034",
- "75569e-254",
- "928609e-261",
- "9210917e+080",
- "84863171e+114",
- "653777767e+273",
- "5232604057e-298",
- "27235667517e-109",
- "653532977297e-123",
- "3142213164987e-294",
- "46202199371337e-072",
- "231010996856685e-073",
- "9324754620109615e+212",
- "78459735791271921e+049",
- "272104041512242479e+200",
- "6802601037806061975e+198",
- "20505426358836677347e-221",
- "836168422905420598437e-234",
- "4891559871276714924261e+222",
-
- // Table 2: Stress Inputs for Conversion to 53-bit Binary, > 1/2 ULP
- "9e-265",
- "85e-037",
- "623e+100",
- "3571e+263",
- "81661e+153",
- "920657e-023",
- "4603285e-024",
- "87575437e-309",
- "245540327e+122",
- "6138508175e+120",
- "83356057653e+193",
- "619534293513e+124",
- "2335141086879e+218",
- "36167929443327e-159",
- "609610927149051e-255",
- "3743626360493413e-165",
- "94080055902682397e-242",
- "899810892172646163e+283",
- "7120190517612959703e+120",
- "25188282901709339043e-252",
- "308984926168550152811e-052",
- "6372891218502368041059e+064",
-
- // Table 14: Stress Inputs for Conversion to 24-bit Binary, <1/2 ULP
- "5e-20",
- "67e+14",
- "985e+15",
- "7693e-42",
- "55895e-16",
- "996622e-44",
- "7038531e-32",
- "60419369e-46",
- "702990899e-20",
- "6930161142e-48",
- "25933168707e+13",
- "596428896559e+20",
-
- // Table 15: Stress Inputs for Conversion to 24-bit Binary, >1/2 ULP
- "3e-23",
- "57e+18",
- "789e-35",
- "2539e-18",
- "76173e+28",
- "887745e-11",
- "5382571e-37",
- "82381273e-35",
- "750486563e-38",
- "3752432815e-39",
- "75224575729e-45",
- "459926601011e+15",
-
- // Constants plundered from strconv/atof_test.go.
-
- "0",
- "1",
- "+1",
- "1e23",
- "1E23",
- "100000000000000000000000",
- "1e-100",
- "123456700",
- "99999999999999974834176",
- "100000000000000000000001",
- "100000000000000008388608",
- "100000000000000016777215",
- "100000000000000016777216",
- "-1",
- "-0.1",
- "-0", // NB: exception made for this input
- "1e-20",
- "625e-3",
-
- // largest float64
- "1.7976931348623157e308",
- "-1.7976931348623157e308",
- // next float64 - too large
- "1.7976931348623159e308",
- "-1.7976931348623159e308",
- // the border is ...158079
- // borderline - okay
- "1.7976931348623158e308",
- "-1.7976931348623158e308",
- // borderline - too large
- "1.797693134862315808e308",
- "-1.797693134862315808e308",
-
- // a little too large
- "1e308",
- "2e308",
- "1e309",
-
- // way too large
- "1e310",
- "-1e310",
- "1e400",
- "-1e400",
- "long:1e400000",
- "long:-1e400000",
-
- // denormalized
- "1e-305",
- "1e-306",
- "1e-307",
- "1e-308",
- "1e-309",
- "1e-310",
- "1e-322",
- // smallest denormal
- "5e-324",
- "4e-324",
- "3e-324",
- // too small
- "2e-324",
- // way too small
- "1e-350",
- "long:1e-400000",
- // way too small, negative
- "-1e-350",
- "long:-1e-400000",
-
- // try to overflow exponent
- // [Disabled: too slow and memory-hungry with rationals.]
- // "1e-4294967296",
- // "1e+4294967296",
- // "1e-18446744073709551616",
- // "1e+18446744073709551616",
-
- // http://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/
- "2.2250738585072011e-308",
-
- // A very large number (initially wrongly parsed by the fast algorithm).
- "4.630813248087435e+307",
-
- // A different kind of very large number.
- "22.222222222222222",
- "long:2." + strings.Repeat("2", 4000) + "e+1",
-
- // Exactly halfway between 1 and math.Nextafter(1, 2).
- // Round to even (down).
- "1.00000000000000011102230246251565404236316680908203125",
- // Slightly lower; still round down.
- "1.00000000000000011102230246251565404236316680908203124",
- // Slightly higher; round up.
- "1.00000000000000011102230246251565404236316680908203126",
- // Slightly higher, but you have to read all the way to the end.
- "long:1.00000000000000011102230246251565404236316680908203125" + strings.Repeat("0", 10000) + "1",
-
- // Smallest denormal, 2^(-1022-52)
- "4.940656458412465441765687928682213723651e-324",
- // Half of smallest denormal, 2^(-1022-53)
- "2.470328229206232720882843964341106861825e-324",
- // A little more than the exact half of smallest denormal
- // 2^-1075 + 2^-1100. (Rounds to 1p-1074.)
- "2.470328302827751011111470718709768633275e-324",
- // The exact halfway between smallest normal and largest denormal:
- // 2^-1022 - 2^-1075. (Rounds to 2^-1022.)
- "2.225073858507201136057409796709131975935e-308",
-
- "1152921504606846975", // 1<<60 - 1
- "-1152921504606846975", // -(1<<60 - 1)
- "1152921504606846977", // 1<<60 + 1
- "-1152921504606846977", // -(1<<60 + 1)
-
- "1/3",
-}
-
-// isFinite reports whether f represents a finite rational value.
-// It is equivalent to !math.IsNan(f) && !math.IsInf(f, 0).
-func isFinite(f float64) bool {
- return math.Abs(f) <= math.MaxFloat64
-}
-
-func TestFloat32SpecialCases(t *testing.T) {
- for _, input := range float64inputs {
- if strings.HasPrefix(input, "long:") {
- if testing.Short() {
- continue
- }
- input = input[len("long:"):]
- }
-
- r, ok := new(Rat).SetString(input)
- if !ok {
- t.Errorf("Rat.SetString(%q) failed", input)
- continue
- }
- f, exact := r.Float32()
-
- // 1. Check string -> Rat -> float32 conversions are
- // consistent with strconv.ParseFloat.
- // Skip this check if the input uses "a/b" rational syntax.
- if !strings.Contains(input, "/") {
- e64, _ := strconv.ParseFloat(input, 32)
- e := float32(e64)
-
- // Careful: negative Rats too small for
- // float64 become -0, but Rat obviously cannot
- // preserve the sign from SetString("-0").
- switch {
- case math.Float32bits(e) == math.Float32bits(f):
- // Ok: bitwise equal.
- case f == 0 && r.Num().BitLen() == 0:
- // Ok: Rat(0) is equivalent to both +/- float64(0).
- default:
- t.Errorf("strconv.ParseFloat(%q) = %g (%b), want %g (%b); delta = %g", input, e, e, f, f, f-e)
- }
- }
-
- if !isFinite(float64(f)) {
- continue
- }
-
- // 2. Check f is best approximation to r.
- if !checkIsBestApprox32(t, f, r) {
- // Append context information.
- t.Errorf("(input was %q)", input)
- }
-
- // 3. Check f->R->f roundtrip is non-lossy.
- checkNonLossyRoundtrip32(t, f)
-
- // 4. Check exactness using slow algorithm.
- if wasExact := new(Rat).SetFloat64(float64(f)).Cmp(r) == 0; wasExact != exact {
- t.Errorf("Rat.SetString(%q).Float32().exact = %t, want %t", input, exact, wasExact)
- }
- }
-}
-
-func TestFloat64SpecialCases(t *testing.T) {
- for _, input := range float64inputs {
- if strings.HasPrefix(input, "long:") {
- if testing.Short() {
- continue
- }
- input = input[len("long:"):]
- }
-
- r, ok := new(Rat).SetString(input)
- if !ok {
- t.Errorf("Rat.SetString(%q) failed", input)
- continue
- }
- f, exact := r.Float64()
-
- // 1. Check string -> Rat -> float64 conversions are
- // consistent with strconv.ParseFloat.
- // Skip this check if the input uses "a/b" rational syntax.
- if !strings.Contains(input, "/") {
- e, _ := strconv.ParseFloat(input, 64)
-
- // Careful: negative Rats too small for
- // float64 become -0, but Rat obviously cannot
- // preserve the sign from SetString("-0").
- switch {
- case math.Float64bits(e) == math.Float64bits(f):
- // Ok: bitwise equal.
- case f == 0 && r.Num().BitLen() == 0:
- // Ok: Rat(0) is equivalent to both +/- float64(0).
- default:
- t.Errorf("strconv.ParseFloat(%q) = %g (%b), want %g (%b); delta = %g", input, e, e, f, f, f-e)
- }
- }
-
- if !isFinite(f) {
- continue
- }
-
- // 2. Check f is best approximation to r.
- if !checkIsBestApprox64(t, f, r) {
- // Append context information.
- t.Errorf("(input was %q)", input)
- }
-
- // 3. Check f->R->f roundtrip is non-lossy.
- checkNonLossyRoundtrip64(t, f)
-
- // 4. Check exactness using slow algorithm.
- if wasExact := new(Rat).SetFloat64(f).Cmp(r) == 0; wasExact != exact {
- t.Errorf("Rat.SetString(%q).Float64().exact = %t, want %t", input, exact, wasExact)
- }
- }
-}
diff --git a/src/cmd/compile/internal/big/ratmarsh.go b/src/cmd/compile/internal/big/ratmarsh.go
deleted file mode 100644
index b82e8d4..0000000
--- a/src/cmd/compile/internal/big/ratmarsh.go
+++ /dev/null
@@ -1,73 +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.
-
-// This file implements encoding/decoding of Rats.
-
-package big
-
-import (
- "encoding/binary"
- "errors"
- "fmt"
-)
-
-// Gob codec version. Permits backward-compatible changes to the encoding.
-const ratGobVersion byte = 1
-
-// GobEncode implements the gob.GobEncoder interface.
-func (x *Rat) GobEncode() ([]byte, error) {
- if x == nil {
- return nil, nil
- }
- buf := make([]byte, 1+4+(len(x.a.abs)+len(x.b.abs))*_S) // extra bytes for version and sign bit (1), and numerator length (4)
- i := x.b.abs.bytes(buf)
- j := x.a.abs.bytes(buf[:i])
- n := i - j
- if int(uint32(n)) != n {
- // this should never happen
- return nil, errors.New("Rat.GobEncode: numerator too large")
- }
- binary.BigEndian.PutUint32(buf[j-4:j], uint32(n))
- j -= 1 + 4
- b := ratGobVersion << 1 // make space for sign bit
- if x.a.neg {
- b |= 1
- }
- buf[j] = b
- return buf[j:], nil
-}
-
-// GobDecode implements the gob.GobDecoder interface.
-func (z *Rat) GobDecode(buf []byte) error {
- if len(buf) == 0 {
- // Other side sent a nil or default value.
- *z = Rat{}
- return nil
- }
- b := buf[0]
- if b>>1 != ratGobVersion {
- return fmt.Errorf("Rat.GobDecode: encoding version %d not supported", b>>1)
- }
- const j = 1 + 4
- i := j + binary.BigEndian.Uint32(buf[j-4:j])
- z.a.neg = b&1 != 0
- z.a.abs = z.a.abs.setBytes(buf[j:i])
- z.b.abs = z.b.abs.setBytes(buf[i:])
- return nil
-}
-
-// MarshalText implements the encoding.TextMarshaler interface.
-func (x *Rat) MarshalText() (text []byte, err error) {
- // TODO(gri): get rid of the []byte/string conversion
- return []byte(x.RatString()), nil
-}
-
-// UnmarshalText implements the encoding.TextUnmarshaler interface.
-func (z *Rat) UnmarshalText(text []byte) error {
- // TODO(gri): get rid of the []byte/string conversion
- if _, ok := z.SetString(string(text)); !ok {
- return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Rat", text)
- }
- return nil
-}
diff --git a/src/cmd/compile/internal/big/ratmarsh_test.go b/src/cmd/compile/internal/big/ratmarsh_test.go
deleted file mode 100644
index 351d109..0000000
--- a/src/cmd/compile/internal/big/ratmarsh_test.go
+++ /dev/null
@@ -1,125 +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.
-
-package big
-
-import (
- "bytes"
- "encoding/gob"
- "encoding/json"
- "encoding/xml"
- "testing"
-)
-
-func TestRatGobEncoding(t *testing.T) {
- var medium bytes.Buffer
- enc := gob.NewEncoder(&medium)
- dec := gob.NewDecoder(&medium)
- for _, test := range encodingTests {
- medium.Reset() // empty buffer for each test case (in case of failures)
- var tx Rat
- tx.SetString(test + ".14159265")
- if err := enc.Encode(&tx); err != nil {
- t.Errorf("encoding of %s failed: %s", &tx, err)
- continue
- }
- var rx Rat
- if err := dec.Decode(&rx); err != nil {
- t.Errorf("decoding of %s failed: %s", &tx, err)
- continue
- }
- if rx.Cmp(&tx) != 0 {
- t.Errorf("transmission of %s failed: got %s want %s", &tx, &rx, &tx)
- }
- }
-}
-
-// Sending a nil Rat pointer (inside a slice) on a round trip through gob should yield a zero.
-// TODO: top-level nils.
-func TestGobEncodingNilRatInSlice(t *testing.T) {
- buf := new(bytes.Buffer)
- enc := gob.NewEncoder(buf)
- dec := gob.NewDecoder(buf)
-
- var in = make([]*Rat, 1)
- err := enc.Encode(&in)
- if err != nil {
- t.Errorf("gob encode failed: %q", err)
- }
- var out []*Rat
- err = dec.Decode(&out)
- if err != nil {
- t.Fatalf("gob decode failed: %q", err)
- }
- if len(out) != 1 {
- t.Fatalf("wrong len; want 1 got %d", len(out))
- }
- var zero Rat
- if out[0].Cmp(&zero) != 0 {
- t.Fatalf("transmission of (*Int)(nil) failed: got %s want 0", out)
- }
-}
-
-var ratNums = []string{
- "-141592653589793238462643383279502884197169399375105820974944592307816406286",
- "-1415926535897932384626433832795028841971",
- "-141592653589793",
- "-1",
- "0",
- "1",
- "141592653589793",
- "1415926535897932384626433832795028841971",
- "141592653589793238462643383279502884197169399375105820974944592307816406286",
-}
-
-var ratDenoms = []string{
- "1",
- "718281828459045",
- "7182818284590452353602874713526624977572",
- "718281828459045235360287471352662497757247093699959574966967627724076630353",
-}
-
-func TestRatJSONEncoding(t *testing.T) {
- for _, num := range ratNums {
- for _, denom := range ratDenoms {
- var tx Rat
- tx.SetString(num + "/" + denom)
- b, err := json.Marshal(&tx)
- if err != nil {
- t.Errorf("marshaling of %s failed: %s", &tx, err)
- continue
- }
- var rx Rat
- if err := json.Unmarshal(b, &rx); err != nil {
- t.Errorf("unmarshaling of %s failed: %s", &tx, err)
- continue
- }
- if rx.Cmp(&tx) != 0 {
- t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx)
- }
- }
- }
-}
-
-func TestRatXMLEncoding(t *testing.T) {
- for _, num := range ratNums {
- for _, denom := range ratDenoms {
- var tx Rat
- tx.SetString(num + "/" + denom)
- b, err := xml.Marshal(&tx)
- if err != nil {
- t.Errorf("marshaling of %s failed: %s", &tx, err)
- continue
- }
- var rx Rat
- if err := xml.Unmarshal(b, &rx); err != nil {
- t.Errorf("unmarshaling of %s failed: %s", &tx, err)
- continue
- }
- if rx.Cmp(&tx) != 0 {
- t.Errorf("XML encoding of %s failed: got %s want %s", &tx, &rx, &tx)
- }
- }
- }
-}
diff --git a/src/cmd/compile/internal/big/roundingmode_string.go b/src/cmd/compile/internal/big/roundingmode_string.go
deleted file mode 100644
index 05024b8..0000000
--- a/src/cmd/compile/internal/big/roundingmode_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// generated by stringer -type=RoundingMode; DO NOT EDIT
-
-package big
-
-import "fmt"
-
-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)
- }
- return _RoundingMode_name[_RoundingMode_index[i]:_RoundingMode_index[i+1]]
-}
diff --git a/src/cmd/compile/internal/big/vendor.bash b/src/cmd/compile/internal/big/vendor.bash
deleted file mode 100755
index ac3ec9b..0000000
--- a/src/cmd/compile/internal/big/vendor.bash
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env bash
-
-# 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.
-
-# Run this script to obtain an up-to-date vendored version of math/big.
-
-BIGDIR=../../../../math/big
-
-# Start from scratch.
-rm *.go
-
-# We don't want any assembly files.
-cp $BIGDIR/*.go .
-
-# Use pure Go arith ops w/o build tag.
-sed 's|^// \+build math_big_pure_go$||' arith_decl_pure.go > arith_decl.go
-rm arith_decl_pure.go
-
-# Import vendored math/big in external tests (e.g., floatexample_test.go).
-for f in *_test.go; do
- sed 's|"math/big"|"cmd/compile/internal/big"|' $f > foo.go
- mv foo.go $f
-done
-
-# gofmt to clean up after sed
-gofmt -w .
-
-# Test that it works
-go test -short
diff --git a/src/cmd/compile/internal/gc/bexport.go b/src/cmd/compile/internal/gc/bexport.go
index ed47854..03223b4 100644
--- a/src/cmd/compile/internal/gc/bexport.go
+++ b/src/cmd/compile/internal/gc/bexport.go
@@ -132,7 +132,7 @@
import (
"bufio"
"bytes"
- "cmd/compile/internal/big"
+ "math/big"
"encoding/binary"
"fmt"
"sort"
diff --git a/src/cmd/compile/internal/gc/bimport.go b/src/cmd/compile/internal/gc/bimport.go
index 92a116b..3c75b8f 100644
--- a/src/cmd/compile/internal/gc/bimport.go
+++ b/src/cmd/compile/internal/gc/bimport.go
@@ -10,7 +10,7 @@
import (
"bufio"
- "cmd/compile/internal/big"
+ "math/big"
"encoding/binary"
"fmt"
"strconv"
diff --git a/src/cmd/compile/internal/gc/mpfloat.go b/src/cmd/compile/internal/gc/mpfloat.go
index 55168e9..c851022 100644
--- a/src/cmd/compile/internal/gc/mpfloat.go
+++ b/src/cmd/compile/internal/gc/mpfloat.go
@@ -5,9 +5,9 @@
package gc
import (
- "cmd/compile/internal/big"
"fmt"
"math"
+ "math/big"
)
// implements float arithmetic
diff --git a/src/cmd/compile/internal/gc/mpint.go b/src/cmd/compile/internal/gc/mpint.go
index 31fbe85..fba8260 100644
--- a/src/cmd/compile/internal/gc/mpint.go
+++ b/src/cmd/compile/internal/gc/mpint.go
@@ -5,8 +5,8 @@
package gc
import (
- "cmd/compile/internal/big"
"fmt"
+ "math/big"
)
// implements integer arithmetic
diff --git a/src/cmd/compile/internal/gc/swt_test.go b/src/cmd/compile/internal/gc/swt_test.go
index 1026202..4139898 100644
--- a/src/cmd/compile/internal/gc/swt_test.go
+++ b/src/cmd/compile/internal/gc/swt_test.go
@@ -5,7 +5,7 @@
package gc
import (
- "cmd/compile/internal/big"
+ "math/big"
"testing"
)
diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go
index c700a5d..136e45ee 100644
--- a/src/cmd/dist/buildtool.go
+++ b/src/cmd/dist/buildtool.go
@@ -18,49 +18,60 @@
// bootstrapDirs is a list of directories holding code that must be
// compiled with a Go 1.4 toolchain to produce the bootstrapTargets.
-// All directories in this list are relative to and must be below $GOROOT/src/cmd.
-// The list is assumed to have two kinds of entries: names without slashes,
-// which are commands, and entries beginning with internal/, which are
-// packages supporting the commands.
+// All directories in this list are relative to and must be below $GOROOT/src.
+//
+// The list has have two kinds of entries: names beginning with cmd/ with
+// no other slashes, which are commands, and other paths, which are packages
+// supporting the commands. Packages in the standard library can be listed
+// if a newer copy needs to be substituted for the Go 1.4 copy when used
+// by the command packages.
+// These will be imported during bootstrap as bootstrap/name, like bootstrap/math/big.
var bootstrapDirs = []string{
- "asm",
- "asm/internal/arch",
- "asm/internal/asm",
- "asm/internal/flags",
- "asm/internal/lex",
- "compile",
- "compile/internal/amd64",
- "compile/internal/arm",
- "compile/internal/arm64",
- "compile/internal/big",
- "compile/internal/gc",
- "compile/internal/mips64",
- "compile/internal/ppc64",
- "compile/internal/s390x",
- "compile/internal/ssa",
- "compile/internal/syntax",
- "compile/internal/x86",
- "internal/bio",
- "internal/gcprog",
- "internal/dwarf",
- "internal/obj",
- "internal/obj/arm",
- "internal/obj/arm64",
- "internal/obj/mips",
- "internal/obj/ppc64",
- "internal/obj/s390x",
- "internal/obj/x86",
- "internal/sys",
- "link",
- "link/internal/amd64",
- "link/internal/arm",
- "link/internal/arm64",
- "link/internal/pe",
- "link/internal/ld",
- "link/internal/mips64",
- "link/internal/ppc64",
- "link/internal/s390x",
- "link/internal/x86",
+ "cmd/asm",
+ "cmd/asm/internal/arch",
+ "cmd/asm/internal/asm",
+ "cmd/asm/internal/flags",
+ "cmd/asm/internal/lex",
+ "cmd/compile",
+ "cmd/compile/internal/amd64",
+ "cmd/compile/internal/arm",
+ "cmd/compile/internal/arm64",
+ "cmd/compile/internal/gc",
+ "cmd/compile/internal/mips64",
+ "cmd/compile/internal/ppc64",
+ "cmd/compile/internal/s390x",
+ "cmd/compile/internal/ssa",
+ "cmd/compile/internal/syntax",
+ "cmd/compile/internal/x86",
+ "cmd/internal/bio",
+ "cmd/internal/gcprog",
+ "cmd/internal/dwarf",
+ "cmd/internal/obj",
+ "cmd/internal/obj/arm",
+ "cmd/internal/obj/arm64",
+ "cmd/internal/obj/mips",
+ "cmd/internal/obj/ppc64",
+ "cmd/internal/obj/s390x",
+ "cmd/internal/obj/x86",
+ "cmd/internal/sys",
+ "cmd/link",
+ "cmd/link/internal/amd64",
+ "cmd/link/internal/arm",
+ "cmd/link/internal/arm64",
+ "cmd/link/internal/ld",
+ "cmd/link/internal/mips64",
+ "cmd/link/internal/pe",
+ "cmd/link/internal/ppc64",
+ "cmd/link/internal/s390x",
+ "cmd/link/internal/x86",
+ "math/big",
+}
+
+// File suffixes that use build tags introduced since Go 1.4.
+// These must not be copied into the bootstrap build directory.
+var ignoreSuffixes = []string{
+ "_arm64.s",
+ "_arm64.go",
}
func bootstrapBuildTools() {
@@ -84,10 +95,16 @@
// Copy source code into $GOROOT/pkg/bootstrap and rewrite import paths.
for _, dir := range bootstrapDirs {
- src := pathf("%s/src/cmd/%s", goroot, dir)
+ src := pathf("%s/src/%s", goroot, dir)
dst := pathf("%s/%s", base, dir)
xmkdirall(dst)
+ Dir:
for _, name := range xreaddirfiles(src) {
+ for _, suf := range ignoreSuffixes {
+ if strings.HasSuffix(name, suf) {
+ continue Dir
+ }
+ }
srcFile := pathf("%s/%s", src, name)
text := readfile(srcFile)
text = bootstrapFixImports(text, srcFile)
@@ -122,10 +139,14 @@
// Run Go 1.4 to build binaries. Use -gcflags=-l to disable inlining to
// workaround bugs in Go 1.4's compiler. See discussion thread:
// https://groups.google.com/d/msg/golang-dev/Ss7mCKsvk8w/Gsq7VYI0AwAJ
- run(workspace, ShowOutput|CheckExit, pathf("%s/bin/go", goroot_bootstrap), "install", "-gcflags=-l", "-v", "bootstrap/...")
+ run(workspace, ShowOutput|CheckExit, pathf("%s/bin/go", goroot_bootstrap), "install", "-gcflags=-l", "-v", "bootstrap/cmd/...")
// Copy binaries into tool binary directory.
for _, name := range bootstrapDirs {
+ if !strings.HasPrefix(name, "cmd/") {
+ continue
+ }
+ name = name[len("cmd/"):]
if !strings.Contains(name, "/") {
copyfile(pathf("%s/%s%s", tooldir, name, exe), pathf("%s/bin/%s%s", workspace, name, exe), writeExec)
}
@@ -148,7 +169,14 @@
}
if strings.HasPrefix(line, `import "`) || strings.HasPrefix(line, `import . "`) ||
inBlock && (strings.HasPrefix(line, "\t\"") || strings.HasPrefix(line, "\t. \"")) {
- lines[i] = strings.Replace(line, `"cmd/`, `"bootstrap/`, -1)
+ line = strings.Replace(line, `"cmd/`, `"bootstrap/cmd/`, -1)
+ for _, dir := range bootstrapDirs {
+ if strings.HasPrefix(dir, "cmd/") {
+ continue
+ }
+ line = strings.Replace(line, `"`+dir+`"`, `"bootstrap/`+dir+`"`, -1)
+ }
+ lines[i] = line
}
}