mirror of
https://github.com/golang/go
synced 2024-07-08 12:18:55 +00:00
cmd/compile/internal/big: update vendored math/big
This updates the big package used by the compiler to match the public big package which contains some updates and bug fixes. Obtained by running vendor.bash in the internal/big directory. No manual changes. Change-Id: I299aecc6599d4a745a721ce48def32449640dbb2 Reviewed-on: https://go-review.googlesource.com/13815 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
e288271773
commit
548041ed08
|
@ -8,6 +8,7 @@ import (
|
|||
"cmd/compile/internal/big"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
)
|
||||
|
||||
func ExampleRat_SetString() {
|
||||
|
@ -49,3 +50,79 @@ func ExampleInt_Scan() {
|
|||
}
|
||||
// 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
|
||||
}
|
||||
|
|
|
@ -125,9 +125,9 @@ func (z *Float) scan(r io.ByteScanner, base int) (f *Float, b int, err error) {
|
|||
// apply 10**exp10
|
||||
p := new(Float).SetPrec(z.Prec() + 64) // use more bits for p -- TODO(gri) what is the right number?
|
||||
if exp10 < 0 {
|
||||
z.uquo(z, p.pow10(-exp10))
|
||||
z.Quo(z, p.pow10(-exp10))
|
||||
} else {
|
||||
z.umul(z, p.pow10(exp10))
|
||||
z.Mul(z, p.pow10(exp10))
|
||||
}
|
||||
|
||||
return
|
||||
|
|
|
@ -367,9 +367,9 @@ func TestFloatText(t *testing.T) {
|
|||
|
||||
// make sure "stupid" exponents don't stall the machine
|
||||
{"1e1000000", 64, 'p', 0, "0x.88b3a28a05eade3ap+3321929"},
|
||||
{"1e1000000000", 64, 'p', 0, "0x.ecc5f45aa573d3p+1538481529"},
|
||||
{"1e1000000000", 64, 'p', 0, "+Inf"},
|
||||
{"1e-1000000", 64, 'p', 0, "0x.efb4542cc8ca418ap-3321928"},
|
||||
{"1e-1000000000", 64, 'p', 0, "0x.8a64dd983a4c7dabp-1538481528"},
|
||||
{"1e-1000000000", 64, 'p', 0, "0"},
|
||||
|
||||
// TODO(gri) need tests for actual large Floats
|
||||
|
||||
|
|
|
@ -500,15 +500,17 @@ func (z *Int) binaryGCD(a, b *Int) *Int {
|
|||
// use one Euclidean iteration to ensure that u and v are approx. the same size
|
||||
switch {
|
||||
case len(a.abs) > len(b.abs):
|
||||
u.Set(b)
|
||||
// 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):
|
||||
u.Set(a)
|
||||
v.Rem(b, a)
|
||||
default:
|
||||
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 {
|
||||
|
|
|
@ -387,6 +387,11 @@ func TestSetBytes(t *testing.T) {
|
|||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
@ -662,6 +667,21 @@ func testGcd(t *testing.T, d, x, y, a, b *Int) {
|
|||
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) {
|
||||
|
|
|
@ -101,31 +101,31 @@ func (x *Int) Format(s fmt.State, ch rune) {
|
|||
digits := x.abs.string(cs)
|
||||
|
||||
// number of characters for the three classes of number padding
|
||||
var left int // space characters to left of digits for right justification ("%8d")
|
||||
var zeroes int // zero characters (actually cs[0]) as left-most digits ("%.8d")
|
||||
var right int // space characters to right of digits for left justification ("%-8d")
|
||||
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:
|
||||
zeroes = precision - len(digits) // count of zero padding
|
||||
zeros = precision - len(digits) // count of zero padding
|
||||
case digits == "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) + zeroes + len(digits)
|
||||
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 zeroes unless precision also specified
|
||||
zeroes = d
|
||||
// pad with zeros unless precision also specified
|
||||
zeros = d
|
||||
default:
|
||||
// pad on the left with spaces
|
||||
left = d
|
||||
|
@ -136,7 +136,7 @@ func (x *Int) Format(s fmt.State, ch rune) {
|
|||
writeMultiple(s, " ", left)
|
||||
writeMultiple(s, sign, 1)
|
||||
writeMultiple(s, prefix, 1)
|
||||
writeMultiple(s, "0", zeroes)
|
||||
writeMultiple(s, "0", zeros)
|
||||
writeMultiple(s, digits, 1)
|
||||
writeMultiple(s, " ", right)
|
||||
}
|
||||
|
|
|
@ -252,14 +252,15 @@ func (x nat) hexString() string {
|
|||
// by len(charset), which must be >= 2 and <= 256.
|
||||
func (x nat) string(charset string) string {
|
||||
b := Word(len(charset))
|
||||
|
||||
// special cases
|
||||
switch {
|
||||
case b < 2 || b > 256:
|
||||
if b < 2 || b > 256 {
|
||||
panic("invalid character set length")
|
||||
case len(x) == 0:
|
||||
}
|
||||
|
||||
// x == 0
|
||||
if len(x) == 0 {
|
||||
return string(charset[0])
|
||||
}
|
||||
// len(x) > 0
|
||||
|
||||
// allocate buffer for conversion
|
||||
i := int(float64(x.bitLen())/math.Log2(float64(b))) + 1 // off by one at most
|
||||
|
@ -267,13 +268,13 @@ func (x nat) string(charset string) string {
|
|||
|
||||
// convert power of two and non power of two bases separately
|
||||
if b == b&-b {
|
||||
// shift is base-b digit size in bits
|
||||
// shift is base b digit size in bits
|
||||
shift := trailingZeroBits(b) // shift > 0 because b >= 2
|
||||
mask := Word(1)<<shift - 1
|
||||
w := x[0]
|
||||
mask := Word(1<<shift - 1)
|
||||
w := x[0] // current word
|
||||
nbits := uint(_W) // number of unprocessed bits in w
|
||||
|
||||
// convert less-significant words
|
||||
// convert less-significant words (include leading zeros)
|
||||
for k := 1; k < len(x); k++ {
|
||||
// convert full digits
|
||||
for nbits >= shift {
|
||||
|
@ -289,7 +290,7 @@ func (x nat) string(charset string) string {
|
|||
w = x[k]
|
||||
nbits = _W
|
||||
} else {
|
||||
// partial digit in current (k-1) and next (k) word
|
||||
// partial digit in current word w (== x[k-1]) and next word x[k]
|
||||
w |= x[k] << nbits
|
||||
i--
|
||||
s[i] = charset[w&mask]
|
||||
|
@ -300,12 +301,11 @@ func (x nat) string(charset string) string {
|
|||
}
|
||||
}
|
||||
|
||||
// convert digits of most-significant word (omit leading zeros)
|
||||
for nbits >= 0 && w != 0 {
|
||||
// convert digits of most-significant word w (omit leading zeros)
|
||||
for w != 0 {
|
||||
i--
|
||||
s[i] = charset[w&mask]
|
||||
w >>= shift
|
||||
nbits -= shift
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -409,9 +409,9 @@ func (q nat) convertWords(s []byte, charset string, b Word, ndigits int, bb Word
|
|||
}
|
||||
}
|
||||
|
||||
// prepend high-order zeroes
|
||||
// prepend high-order zeros
|
||||
zero := charset[0]
|
||||
for i > 0 { // while need more leading zeroes
|
||||
for i > 0 { // while need more leading zeros
|
||||
i--
|
||||
s[i] = zero
|
||||
}
|
||||
|
@ -425,7 +425,7 @@ var leafSize int = 8 // number of Word-size binary values treat as a monolithic
|
|||
|
||||
type divisor struct {
|
||||
bbb nat // divisor
|
||||
nbits int // bit length of divisor (discounting leading zeroes) ~= log2(bbb)
|
||||
nbits int // bit length of divisor (discounting leading zeros) ~= log2(bbb)
|
||||
ndigits int // digit length of divisor in terms of output base digits
|
||||
}
|
||||
|
||||
|
|
|
@ -205,7 +205,8 @@ func (x *Rat) RatString() string {
|
|||
}
|
||||
|
||||
// FloatString returns a string representation of x in decimal form with prec
|
||||
// digits of precision after the decimal point and the last digit rounded.
|
||||
// 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 {
|
||||
if x.IsInt() {
|
||||
s := x.a.String()
|
||||
|
|
|
@ -113,6 +113,8 @@ var floatStringTests = []struct {
|
|||
{"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"},
|
||||
|
|
Loading…
Reference in New Issue
Block a user