1
0
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:
Robert Griesemer 2015-08-21 11:33:25 -07:00
parent e288271773
commit 548041ed08
9 changed files with 134 additions and 32 deletions

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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) {

View File

@ -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)
}

View File

@ -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
}

View File

@ -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()

View File

@ -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"},