github.com/bgentry/go@v0.0.0-20150121062915-6cf5a733d54d/src/math/big/rat.go (about)

     1  // Copyright 2010 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // This file implements multi-precision rational numbers.
     6  
     7  package big
     8  
     9  import (
    10  	"encoding/binary"
    11  	"errors"
    12  	"fmt"
    13  	"io"
    14  	"math"
    15  	"strconv"
    16  	"strings"
    17  )
    18  
    19  // A Rat represents a quotient a/b of arbitrary precision.
    20  // The zero value for a Rat represents the value 0.
    21  type Rat struct {
    22  	// To make zero values for Rat work w/o initialization,
    23  	// a zero value of b (len(b) == 0) acts like b == 1.
    24  	// a.neg determines the sign of the Rat, b.neg is ignored.
    25  	a, b Int
    26  }
    27  
    28  // NewRat creates a new Rat with numerator a and denominator b.
    29  func NewRat(a, b int64) *Rat {
    30  	return new(Rat).SetFrac64(a, b)
    31  }
    32  
    33  // SetFloat64 sets z to exactly f and returns z.
    34  // If f is not finite, SetFloat returns nil.
    35  func (z *Rat) SetFloat64(f float64) *Rat {
    36  	const expMask = 1<<11 - 1
    37  	bits := math.Float64bits(f)
    38  	mantissa := bits & (1<<52 - 1)
    39  	exp := int((bits >> 52) & expMask)
    40  	switch exp {
    41  	case expMask: // non-finite
    42  		return nil
    43  	case 0: // denormal
    44  		exp -= 1022
    45  	default: // normal
    46  		mantissa |= 1 << 52
    47  		exp -= 1023
    48  	}
    49  
    50  	shift := 52 - exp
    51  
    52  	// Optimization (?): partially pre-normalise.
    53  	for mantissa&1 == 0 && shift > 0 {
    54  		mantissa >>= 1
    55  		shift--
    56  	}
    57  
    58  	z.a.SetUint64(mantissa)
    59  	z.a.neg = f < 0
    60  	z.b.Set(intOne)
    61  	if shift > 0 {
    62  		z.b.Lsh(&z.b, uint(shift))
    63  	} else {
    64  		z.a.Lsh(&z.a, uint(-shift))
    65  	}
    66  	return z.norm()
    67  }
    68  
    69  // quotToFloat32 returns the non-negative float32 value
    70  // nearest to the quotient a/b, using round-to-even in
    71  // halfway cases.  It does not mutate its arguments.
    72  // Preconditions: b is non-zero; a and b have no common factors.
    73  func quotToFloat32(a, b nat) (f float32, exact bool) {
    74  	const (
    75  		// float size in bits
    76  		Fsize = 32
    77  
    78  		// mantissa
    79  		Msize  = 23
    80  		Msize1 = Msize + 1 // incl. implicit 1
    81  		Msize2 = Msize1 + 1
    82  
    83  		// exponent
    84  		Esize = Fsize - Msize1
    85  		Ebias = 1<<(Esize-1) - 1
    86  		Emin  = 1 - Ebias
    87  		Emax  = Ebias
    88  	)
    89  
    90  	// TODO(adonovan): specialize common degenerate cases: 1.0, integers.
    91  	alen := a.bitLen()
    92  	if alen == 0 {
    93  		return 0, true
    94  	}
    95  	blen := b.bitLen()
    96  	if blen == 0 {
    97  		panic("division by zero")
    98  	}
    99  
   100  	// 1. Left-shift A or B such that quotient A/B is in [1<<Msize1, 1<<(Msize2+1)
   101  	// (Msize2 bits if A < B when they are left-aligned, Msize2+1 bits if A >= B).
   102  	// This is 2 or 3 more than the float32 mantissa field width of Msize:
   103  	// - the optional extra bit is shifted away in step 3 below.
   104  	// - the high-order 1 is omitted in "normal" representation;
   105  	// - the low-order 1 will be used during rounding then discarded.
   106  	exp := alen - blen
   107  	var a2, b2 nat
   108  	a2 = a2.set(a)
   109  	b2 = b2.set(b)
   110  	if shift := Msize2 - exp; shift > 0 {
   111  		a2 = a2.shl(a2, uint(shift))
   112  	} else if shift < 0 {
   113  		b2 = b2.shl(b2, uint(-shift))
   114  	}
   115  
   116  	// 2. Compute quotient and remainder (q, r).  NB: due to the
   117  	// extra shift, the low-order bit of q is logically the
   118  	// high-order bit of r.
   119  	var q nat
   120  	q, r := q.div(a2, a2, b2) // (recycle a2)
   121  	mantissa := low32(q)
   122  	haveRem := len(r) > 0 // mantissa&1 && !haveRem => remainder is exactly half
   123  
   124  	// 3. If quotient didn't fit in Msize2 bits, redo division by b2<<1
   125  	// (in effect---we accomplish this incrementally).
   126  	if mantissa>>Msize2 == 1 {
   127  		if mantissa&1 == 1 {
   128  			haveRem = true
   129  		}
   130  		mantissa >>= 1
   131  		exp++
   132  	}
   133  	if mantissa>>Msize1 != 1 {
   134  		panic(fmt.Sprintf("expected exactly %d bits of result", Msize2))
   135  	}
   136  
   137  	// 4. Rounding.
   138  	if Emin-Msize <= exp && exp <= Emin {
   139  		// Denormal case; lose 'shift' bits of precision.
   140  		shift := uint(Emin - (exp - 1)) // [1..Esize1)
   141  		lostbits := mantissa & (1<<shift - 1)
   142  		haveRem = haveRem || lostbits != 0
   143  		mantissa >>= shift
   144  		exp = 2 - Ebias // == exp + shift
   145  	}
   146  	// Round q using round-half-to-even.
   147  	exact = !haveRem
   148  	if mantissa&1 != 0 {
   149  		exact = false
   150  		if haveRem || mantissa&2 != 0 {
   151  			if mantissa++; mantissa >= 1<<Msize2 {
   152  				// Complete rollover 11...1 => 100...0, so shift is safe
   153  				mantissa >>= 1
   154  				exp++
   155  			}
   156  		}
   157  	}
   158  	mantissa >>= 1 // discard rounding bit.  Mantissa now scaled by 1<<Msize1.
   159  
   160  	f = float32(math.Ldexp(float64(mantissa), exp-Msize1))
   161  	if math.IsInf(float64(f), 0) {
   162  		exact = false
   163  	}
   164  	return
   165  }
   166  
   167  // quotToFloat64 returns the non-negative float64 value
   168  // nearest to the quotient a/b, using round-to-even in
   169  // halfway cases.  It does not mutate its arguments.
   170  // Preconditions: b is non-zero; a and b have no common factors.
   171  func quotToFloat64(a, b nat) (f float64, exact bool) {
   172  	const (
   173  		// float size in bits
   174  		Fsize = 64
   175  
   176  		// mantissa
   177  		Msize  = 52
   178  		Msize1 = Msize + 1 // incl. implicit 1
   179  		Msize2 = Msize1 + 1
   180  
   181  		// exponent
   182  		Esize = Fsize - Msize1
   183  		Ebias = 1<<(Esize-1) - 1
   184  		Emin  = 1 - Ebias
   185  		Emax  = Ebias
   186  	)
   187  
   188  	// TODO(adonovan): specialize common degenerate cases: 1.0, integers.
   189  	alen := a.bitLen()
   190  	if alen == 0 {
   191  		return 0, true
   192  	}
   193  	blen := b.bitLen()
   194  	if blen == 0 {
   195  		panic("division by zero")
   196  	}
   197  
   198  	// 1. Left-shift A or B such that quotient A/B is in [1<<Msize1, 1<<(Msize2+1)
   199  	// (Msize2 bits if A < B when they are left-aligned, Msize2+1 bits if A >= B).
   200  	// This is 2 or 3 more than the float64 mantissa field width of Msize:
   201  	// - the optional extra bit is shifted away in step 3 below.
   202  	// - the high-order 1 is omitted in "normal" representation;
   203  	// - the low-order 1 will be used during rounding then discarded.
   204  	exp := alen - blen
   205  	var a2, b2 nat
   206  	a2 = a2.set(a)
   207  	b2 = b2.set(b)
   208  	if shift := Msize2 - exp; shift > 0 {
   209  		a2 = a2.shl(a2, uint(shift))
   210  	} else if shift < 0 {
   211  		b2 = b2.shl(b2, uint(-shift))
   212  	}
   213  
   214  	// 2. Compute quotient and remainder (q, r).  NB: due to the
   215  	// extra shift, the low-order bit of q is logically the
   216  	// high-order bit of r.
   217  	var q nat
   218  	q, r := q.div(a2, a2, b2) // (recycle a2)
   219  	mantissa := low64(q)
   220  	haveRem := len(r) > 0 // mantissa&1 && !haveRem => remainder is exactly half
   221  
   222  	// 3. If quotient didn't fit in Msize2 bits, redo division by b2<<1
   223  	// (in effect---we accomplish this incrementally).
   224  	if mantissa>>Msize2 == 1 {
   225  		if mantissa&1 == 1 {
   226  			haveRem = true
   227  		}
   228  		mantissa >>= 1
   229  		exp++
   230  	}
   231  	if mantissa>>Msize1 != 1 {
   232  		panic(fmt.Sprintf("expected exactly %d bits of result", Msize2))
   233  	}
   234  
   235  	// 4. Rounding.
   236  	if Emin-Msize <= exp && exp <= Emin {
   237  		// Denormal case; lose 'shift' bits of precision.
   238  		shift := uint(Emin - (exp - 1)) // [1..Esize1)
   239  		lostbits := mantissa & (1<<shift - 1)
   240  		haveRem = haveRem || lostbits != 0
   241  		mantissa >>= shift
   242  		exp = 2 - Ebias // == exp + shift
   243  	}
   244  	// Round q using round-half-to-even.
   245  	exact = !haveRem
   246  	if mantissa&1 != 0 {
   247  		exact = false
   248  		if haveRem || mantissa&2 != 0 {
   249  			if mantissa++; mantissa >= 1<<Msize2 {
   250  				// Complete rollover 11...1 => 100...0, so shift is safe
   251  				mantissa >>= 1
   252  				exp++
   253  			}
   254  		}
   255  	}
   256  	mantissa >>= 1 // discard rounding bit.  Mantissa now scaled by 1<<Msize1.
   257  
   258  	f = math.Ldexp(float64(mantissa), exp-Msize1)
   259  	if math.IsInf(f, 0) {
   260  		exact = false
   261  	}
   262  	return
   263  }
   264  
   265  // Float32 returns the nearest float32 value for x and a bool indicating
   266  // whether f represents x exactly. If the magnitude of x is too large to
   267  // be represented by a float32, f is an infinity and exact is false.
   268  // The sign of f always matches the sign of x, even if f == 0.
   269  func (x *Rat) Float32() (f float32, exact bool) {
   270  	b := x.b.abs
   271  	if len(b) == 0 {
   272  		b = b.set(natOne) // materialize denominator
   273  	}
   274  	f, exact = quotToFloat32(x.a.abs, b)
   275  	if x.a.neg {
   276  		f = -f
   277  	}
   278  	return
   279  }
   280  
   281  // Float64 returns the nearest float64 value for x and a bool indicating
   282  // whether f represents x exactly. If the magnitude of x is too large to
   283  // be represented by a float64, f is an infinity and exact is false.
   284  // The sign of f always matches the sign of x, even if f == 0.
   285  func (x *Rat) Float64() (f float64, exact bool) {
   286  	b := x.b.abs
   287  	if len(b) == 0 {
   288  		b = b.set(natOne) // materialize denominator
   289  	}
   290  	f, exact = quotToFloat64(x.a.abs, b)
   291  	if x.a.neg {
   292  		f = -f
   293  	}
   294  	return
   295  }
   296  
   297  // SetFrac sets z to a/b and returns z.
   298  func (z *Rat) SetFrac(a, b *Int) *Rat {
   299  	z.a.neg = a.neg != b.neg
   300  	babs := b.abs
   301  	if len(babs) == 0 {
   302  		panic("division by zero")
   303  	}
   304  	if &z.a == b || alias(z.a.abs, babs) {
   305  		babs = nat(nil).set(babs) // make a copy
   306  	}
   307  	z.a.abs = z.a.abs.set(a.abs)
   308  	z.b.abs = z.b.abs.set(babs)
   309  	return z.norm()
   310  }
   311  
   312  // SetFrac64 sets z to a/b and returns z.
   313  func (z *Rat) SetFrac64(a, b int64) *Rat {
   314  	z.a.SetInt64(a)
   315  	if b == 0 {
   316  		panic("division by zero")
   317  	}
   318  	if b < 0 {
   319  		b = -b
   320  		z.a.neg = !z.a.neg
   321  	}
   322  	z.b.abs = z.b.abs.setUint64(uint64(b))
   323  	return z.norm()
   324  }
   325  
   326  // SetInt sets z to x (by making a copy of x) and returns z.
   327  func (z *Rat) SetInt(x *Int) *Rat {
   328  	z.a.Set(x)
   329  	z.b.abs = z.b.abs.make(0)
   330  	return z
   331  }
   332  
   333  // SetInt64 sets z to x and returns z.
   334  func (z *Rat) SetInt64(x int64) *Rat {
   335  	z.a.SetInt64(x)
   336  	z.b.abs = z.b.abs.make(0)
   337  	return z
   338  }
   339  
   340  // Set sets z to x (by making a copy of x) and returns z.
   341  func (z *Rat) Set(x *Rat) *Rat {
   342  	if z != x {
   343  		z.a.Set(&x.a)
   344  		z.b.Set(&x.b)
   345  	}
   346  	return z
   347  }
   348  
   349  // Abs sets z to |x| (the absolute value of x) and returns z.
   350  func (z *Rat) Abs(x *Rat) *Rat {
   351  	z.Set(x)
   352  	z.a.neg = false
   353  	return z
   354  }
   355  
   356  // Neg sets z to -x and returns z.
   357  func (z *Rat) Neg(x *Rat) *Rat {
   358  	z.Set(x)
   359  	z.a.neg = len(z.a.abs) > 0 && !z.a.neg // 0 has no sign
   360  	return z
   361  }
   362  
   363  // Inv sets z to 1/x and returns z.
   364  func (z *Rat) Inv(x *Rat) *Rat {
   365  	if len(x.a.abs) == 0 {
   366  		panic("division by zero")
   367  	}
   368  	z.Set(x)
   369  	a := z.b.abs
   370  	if len(a) == 0 {
   371  		a = a.set(natOne) // materialize numerator
   372  	}
   373  	b := z.a.abs
   374  	if b.cmp(natOne) == 0 {
   375  		b = b.make(0) // normalize denominator
   376  	}
   377  	z.a.abs, z.b.abs = a, b // sign doesn't change
   378  	return z
   379  }
   380  
   381  // Sign returns:
   382  //
   383  //	-1 if x <  0
   384  //	 0 if x == 0
   385  //	+1 if x >  0
   386  //
   387  func (x *Rat) Sign() int {
   388  	return x.a.Sign()
   389  }
   390  
   391  // IsInt returns true if the denominator of x is 1.
   392  func (x *Rat) IsInt() bool {
   393  	return len(x.b.abs) == 0 || x.b.abs.cmp(natOne) == 0
   394  }
   395  
   396  // Num returns the numerator of x; it may be <= 0.
   397  // The result is a reference to x's numerator; it
   398  // may change if a new value is assigned to x, and vice versa.
   399  // The sign of the numerator corresponds to the sign of x.
   400  func (x *Rat) Num() *Int {
   401  	return &x.a
   402  }
   403  
   404  // Denom returns the denominator of x; it is always > 0.
   405  // The result is a reference to x's denominator; it
   406  // may change if a new value is assigned to x, and vice versa.
   407  func (x *Rat) Denom() *Int {
   408  	x.b.neg = false // the result is always >= 0
   409  	if len(x.b.abs) == 0 {
   410  		x.b.abs = x.b.abs.set(natOne) // materialize denominator
   411  	}
   412  	return &x.b
   413  }
   414  
   415  func (z *Rat) norm() *Rat {
   416  	switch {
   417  	case len(z.a.abs) == 0:
   418  		// z == 0 - normalize sign and denominator
   419  		z.a.neg = false
   420  		z.b.abs = z.b.abs.make(0)
   421  	case len(z.b.abs) == 0:
   422  		// z is normalized int - nothing to do
   423  	case z.b.abs.cmp(natOne) == 0:
   424  		// z is int - normalize denominator
   425  		z.b.abs = z.b.abs.make(0)
   426  	default:
   427  		neg := z.a.neg
   428  		z.a.neg = false
   429  		z.b.neg = false
   430  		if f := NewInt(0).binaryGCD(&z.a, &z.b); f.Cmp(intOne) != 0 {
   431  			z.a.abs, _ = z.a.abs.div(nil, z.a.abs, f.abs)
   432  			z.b.abs, _ = z.b.abs.div(nil, z.b.abs, f.abs)
   433  			if z.b.abs.cmp(natOne) == 0 {
   434  				// z is int - normalize denominator
   435  				z.b.abs = z.b.abs.make(0)
   436  			}
   437  		}
   438  		z.a.neg = neg
   439  	}
   440  	return z
   441  }
   442  
   443  // mulDenom sets z to the denominator product x*y (by taking into
   444  // account that 0 values for x or y must be interpreted as 1) and
   445  // returns z.
   446  func mulDenom(z, x, y nat) nat {
   447  	switch {
   448  	case len(x) == 0:
   449  		return z.set(y)
   450  	case len(y) == 0:
   451  		return z.set(x)
   452  	}
   453  	return z.mul(x, y)
   454  }
   455  
   456  // scaleDenom computes x*f.
   457  // If f == 0 (zero value of denominator), the result is (a copy of) x.
   458  func scaleDenom(x *Int, f nat) *Int {
   459  	var z Int
   460  	if len(f) == 0 {
   461  		return z.Set(x)
   462  	}
   463  	z.abs = z.abs.mul(x.abs, f)
   464  	z.neg = x.neg
   465  	return &z
   466  }
   467  
   468  // Cmp compares x and y and returns:
   469  //
   470  //   -1 if x <  y
   471  //    0 if x == y
   472  //   +1 if x >  y
   473  //
   474  func (x *Rat) Cmp(y *Rat) int {
   475  	return scaleDenom(&x.a, y.b.abs).Cmp(scaleDenom(&y.a, x.b.abs))
   476  }
   477  
   478  // Add sets z to the sum x+y and returns z.
   479  func (z *Rat) Add(x, y *Rat) *Rat {
   480  	a1 := scaleDenom(&x.a, y.b.abs)
   481  	a2 := scaleDenom(&y.a, x.b.abs)
   482  	z.a.Add(a1, a2)
   483  	z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
   484  	return z.norm()
   485  }
   486  
   487  // Sub sets z to the difference x-y and returns z.
   488  func (z *Rat) Sub(x, y *Rat) *Rat {
   489  	a1 := scaleDenom(&x.a, y.b.abs)
   490  	a2 := scaleDenom(&y.a, x.b.abs)
   491  	z.a.Sub(a1, a2)
   492  	z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
   493  	return z.norm()
   494  }
   495  
   496  // Mul sets z to the product x*y and returns z.
   497  func (z *Rat) Mul(x, y *Rat) *Rat {
   498  	z.a.Mul(&x.a, &y.a)
   499  	z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
   500  	return z.norm()
   501  }
   502  
   503  // Quo sets z to the quotient x/y and returns z.
   504  // If y == 0, a division-by-zero run-time panic occurs.
   505  func (z *Rat) Quo(x, y *Rat) *Rat {
   506  	if len(y.a.abs) == 0 {
   507  		panic("division by zero")
   508  	}
   509  	a := scaleDenom(&x.a, y.b.abs)
   510  	b := scaleDenom(&y.a, x.b.abs)
   511  	z.a.abs = a.abs
   512  	z.b.abs = b.abs
   513  	z.a.neg = a.neg != b.neg
   514  	return z.norm()
   515  }
   516  
   517  func ratTok(ch rune) bool {
   518  	return strings.IndexRune("+-/0123456789.eE", ch) >= 0
   519  }
   520  
   521  // Scan is a support routine for fmt.Scanner. It accepts the formats
   522  // 'e', 'E', 'f', 'F', 'g', 'G', and 'v'. All formats are equivalent.
   523  func (z *Rat) Scan(s fmt.ScanState, ch rune) error {
   524  	tok, err := s.Token(true, ratTok)
   525  	if err != nil {
   526  		return err
   527  	}
   528  	if strings.IndexRune("efgEFGv", ch) < 0 {
   529  		return errors.New("Rat.Scan: invalid verb")
   530  	}
   531  	if _, ok := z.SetString(string(tok)); !ok {
   532  		return errors.New("Rat.Scan: invalid syntax")
   533  	}
   534  	return nil
   535  }
   536  
   537  // SetString sets z to the value of s and returns z and a boolean indicating
   538  // success. s can be given as a fraction "a/b" or as a floating-point number
   539  // optionally followed by an exponent. If the operation failed, the value of
   540  // z is undefined but the returned value is nil.
   541  func (z *Rat) SetString(s string) (*Rat, bool) {
   542  	if len(s) == 0 {
   543  		return nil, false
   544  	}
   545  	// len(s) > 0
   546  
   547  	// parse fraction a/b, if any
   548  	if sep := strings.Index(s, "/"); sep >= 0 {
   549  		if _, ok := z.a.SetString(s[:sep], 10); !ok {
   550  			return nil, false
   551  		}
   552  		s = s[sep+1:]
   553  		var err error
   554  		if z.b.abs, _, _, err = z.b.abs.scan(strings.NewReader(s), 10); err != nil {
   555  			return nil, false
   556  		}
   557  		if len(z.b.abs) == 0 {
   558  			return nil, false
   559  		}
   560  		return z.norm(), true
   561  	}
   562  
   563  	// parse floating-point number
   564  
   565  	// parse sign
   566  	var neg bool
   567  	switch s[0] {
   568  	case '-':
   569  		neg = true
   570  		fallthrough
   571  	case '+':
   572  		s = s[1:]
   573  	}
   574  
   575  	// parse exponent, if any
   576  	var exp int64
   577  	if sep := strings.IndexAny(s, "eE"); sep >= 0 {
   578  		var err error
   579  		if exp, err = strconv.ParseInt(s[sep+1:], 10, 64); err != nil {
   580  			return nil, false
   581  		}
   582  		s = s[:sep]
   583  	}
   584  
   585  	// parse mantissa
   586  	var err error
   587  	var ecorr int // exponent correction, valid if ecorr <= 0
   588  	r := strings.NewReader(s)
   589  	if z.a.abs, _, ecorr, err = z.a.abs.scan(r, 1); err != nil {
   590  		return nil, false
   591  	}
   592  
   593  	// there should be no unread characters left
   594  	if _, _, err = r.ReadRune(); err != io.EOF {
   595  		return nil, false
   596  	}
   597  
   598  	// correct exponent
   599  	if ecorr < 0 {
   600  		exp += int64(ecorr)
   601  	}
   602  
   603  	// compute exponent factor
   604  	expabs := exp
   605  	if expabs < 0 {
   606  		expabs = -expabs
   607  	}
   608  	powTen := nat(nil).expNN(natTen, nat(nil).setWord(Word(expabs)), nil)
   609  
   610  	// complete fraction
   611  	if exp < 0 {
   612  		z.b.abs = powTen
   613  		z.norm()
   614  	} else {
   615  		z.a.abs = z.a.abs.mul(z.a.abs, powTen)
   616  		z.b.abs = z.b.abs[:0]
   617  	}
   618  
   619  	z.a.neg = neg && len(z.a.abs) > 0 // 0 has no sign
   620  
   621  	return z, true
   622  }
   623  
   624  // String returns a string representation of x in the form "a/b" (even if b == 1).
   625  func (x *Rat) String() string {
   626  	s := "/1"
   627  	if len(x.b.abs) != 0 {
   628  		s = "/" + x.b.abs.decimalString()
   629  	}
   630  	return x.a.String() + s
   631  }
   632  
   633  // RatString returns a string representation of x in the form "a/b" if b != 1,
   634  // and in the form "a" if b == 1.
   635  func (x *Rat) RatString() string {
   636  	if x.IsInt() {
   637  		return x.a.String()
   638  	}
   639  	return x.String()
   640  }
   641  
   642  // FloatString returns a string representation of x in decimal form with prec
   643  // digits of precision after the decimal point and the last digit rounded.
   644  func (x *Rat) FloatString(prec int) string {
   645  	if x.IsInt() {
   646  		s := x.a.String()
   647  		if prec > 0 {
   648  			s += "." + strings.Repeat("0", prec)
   649  		}
   650  		return s
   651  	}
   652  	// x.b.abs != 0
   653  
   654  	q, r := nat(nil).div(nat(nil), x.a.abs, x.b.abs)
   655  
   656  	p := natOne
   657  	if prec > 0 {
   658  		p = nat(nil).expNN(natTen, nat(nil).setUint64(uint64(prec)), nil)
   659  	}
   660  
   661  	r = r.mul(r, p)
   662  	r, r2 := r.div(nat(nil), r, x.b.abs)
   663  
   664  	// see if we need to round up
   665  	r2 = r2.add(r2, r2)
   666  	if x.b.abs.cmp(r2) <= 0 {
   667  		r = r.add(r, natOne)
   668  		if r.cmp(p) >= 0 {
   669  			q = nat(nil).add(q, natOne)
   670  			r = nat(nil).sub(r, p)
   671  		}
   672  	}
   673  
   674  	s := q.decimalString()
   675  	if x.a.neg {
   676  		s = "-" + s
   677  	}
   678  
   679  	if prec > 0 {
   680  		rs := r.decimalString()
   681  		leadingZeros := prec - len(rs)
   682  		s += "." + strings.Repeat("0", leadingZeros) + rs
   683  	}
   684  
   685  	return s
   686  }
   687  
   688  // Gob codec version. Permits backward-compatible changes to the encoding.
   689  const ratGobVersion byte = 1
   690  
   691  // GobEncode implements the gob.GobEncoder interface.
   692  func (x *Rat) GobEncode() ([]byte, error) {
   693  	if x == nil {
   694  		return nil, nil
   695  	}
   696  	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)
   697  	i := x.b.abs.bytes(buf)
   698  	j := x.a.abs.bytes(buf[:i])
   699  	n := i - j
   700  	if int(uint32(n)) != n {
   701  		// this should never happen
   702  		return nil, errors.New("Rat.GobEncode: numerator too large")
   703  	}
   704  	binary.BigEndian.PutUint32(buf[j-4:j], uint32(n))
   705  	j -= 1 + 4
   706  	b := ratGobVersion << 1 // make space for sign bit
   707  	if x.a.neg {
   708  		b |= 1
   709  	}
   710  	buf[j] = b
   711  	return buf[j:], nil
   712  }
   713  
   714  // GobDecode implements the gob.GobDecoder interface.
   715  func (z *Rat) GobDecode(buf []byte) error {
   716  	if len(buf) == 0 {
   717  		// Other side sent a nil or default value.
   718  		*z = Rat{}
   719  		return nil
   720  	}
   721  	b := buf[0]
   722  	if b>>1 != ratGobVersion {
   723  		return errors.New(fmt.Sprintf("Rat.GobDecode: encoding version %d not supported", b>>1))
   724  	}
   725  	const j = 1 + 4
   726  	i := j + binary.BigEndian.Uint32(buf[j-4:j])
   727  	z.a.neg = b&1 != 0
   728  	z.a.abs = z.a.abs.setBytes(buf[j:i])
   729  	z.b.abs = z.b.abs.setBytes(buf[i:])
   730  	return nil
   731  }
   732  
   733  // MarshalText implements the encoding.TextMarshaler interface.
   734  func (r *Rat) MarshalText() (text []byte, err error) {
   735  	return []byte(r.RatString()), nil
   736  }
   737  
   738  // UnmarshalText implements the encoding.TextUnmarshaler interface.
   739  func (r *Rat) UnmarshalText(text []byte) error {
   740  	if _, ok := r.SetString(string(text)); !ok {
   741  		return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Rat", text)
   742  	}
   743  	return nil
   744  }