github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/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 "math" 14 "strings" 15 ) 16 17 // A Rat represents a quotient a/b of arbitrary precision. 18 // The zero value for a Rat represents the value 0. 19 type Rat struct { 20 // To make zero values for Rat work w/o initialization, 21 // a zero value of b (len(b) == 0) acts like b == 1. 22 // a.neg determines the sign of the Rat, b.neg is ignored. 23 a, b Int 24 } 25 26 // NewRat creates a new Rat with numerator a and denominator b. 27 func NewRat(a, b int64) *Rat { 28 return new(Rat).SetFrac64(a, b) 29 } 30 31 // SetFloat64 sets z to exactly f and returns z. 32 // If f is not finite, SetFloat returns nil. 33 func (z *Rat) SetFloat64(f float64) *Rat { 34 const expMask = 1<<11 - 1 35 bits := math.Float64bits(f) 36 mantissa := bits & (1<<52 - 1) 37 exp := int((bits >> 52) & expMask) 38 switch exp { 39 case expMask: // non-finite 40 return nil 41 case 0: // denormal 42 exp -= 1022 43 default: // normal 44 mantissa |= 1 << 52 45 exp -= 1023 46 } 47 48 shift := 52 - exp 49 50 // Optimisation (?): partially pre-normalise. 51 for mantissa&1 == 0 && shift > 0 { 52 mantissa >>= 1 53 shift-- 54 } 55 56 z.a.SetUint64(mantissa) 57 z.a.neg = f < 0 58 z.b.Set(intOne) 59 if shift > 0 { 60 z.b.Lsh(&z.b, uint(shift)) 61 } else { 62 z.a.Lsh(&z.a, uint(-shift)) 63 } 64 return z.norm() 65 } 66 67 // isFinite reports whether f represents a finite rational value. 68 // It is equivalent to !math.IsNan(f) && !math.IsInf(f, 0). 69 func isFinite(f float64) bool { 70 return math.Abs(f) <= math.MaxFloat64 71 } 72 73 // low64 returns the least significant 64 bits of natural number z. 74 func low64(z nat) uint64 { 75 if len(z) == 0 { 76 return 0 77 } 78 if _W == 32 && len(z) > 1 { 79 return uint64(z[1])<<32 | uint64(z[0]) 80 } 81 return uint64(z[0]) 82 } 83 84 // quotToFloat returns the non-negative IEEE 754 double-precision 85 // value nearest to the quotient a/b, using round-to-even in halfway 86 // cases. It does not mutate its arguments. 87 // Preconditions: b is non-zero; a and b have no common factors. 88 func quotToFloat(a, b nat) (f float64, exact bool) { 89 // TODO(adonovan): specialize common degenerate cases: 1.0, integers. 90 alen := a.bitLen() 91 if alen == 0 { 92 return 0, true 93 } 94 blen := b.bitLen() 95 if blen == 0 { 96 panic("division by zero") 97 } 98 99 // 1. Left-shift A or B such that quotient A/B is in [1<<53, 1<<55). 100 // (54 bits if A<B when they are left-aligned, 55 bits if A>=B.) 101 // This is 2 or 3 more than the float64 mantissa field width of 52: 102 // - the optional extra bit is shifted away in step 3 below. 103 // - the high-order 1 is omitted in float64 "normal" representation; 104 // - the low-order 1 will be used during rounding then discarded. 105 exp := alen - blen 106 var a2, b2 nat 107 a2 = a2.set(a) 108 b2 = b2.set(b) 109 if shift := 54 - exp; shift > 0 { 110 a2 = a2.shl(a2, uint(shift)) 111 } else if shift < 0 { 112 b2 = b2.shl(b2, uint(-shift)) 113 } 114 115 // 2. Compute quotient and remainder (q, r). NB: due to the 116 // extra shift, the low-order bit of q is logically the 117 // high-order bit of r. 118 var q nat 119 q, r := q.div(a2, a2, b2) // (recycle a2) 120 mantissa := low64(q) 121 haveRem := len(r) > 0 // mantissa&1 && !haveRem => remainder is exactly half 122 123 // 3. If quotient didn't fit in 54 bits, re-do division by b2<<1 124 // (in effect---we accomplish this incrementally). 125 if mantissa>>54 == 1 { 126 if mantissa&1 == 1 { 127 haveRem = true 128 } 129 mantissa >>= 1 130 exp++ 131 } 132 if mantissa>>53 != 1 { 133 panic("expected exactly 54 bits of result") 134 } 135 136 // 4. Rounding. 137 if -1022-52 <= exp && exp <= -1022 { 138 // Denormal case; lose 'shift' bits of precision. 139 shift := uint64(-1022 - (exp - 1)) // [1..53) 140 lostbits := mantissa & (1<<shift - 1) 141 haveRem = haveRem || lostbits != 0 142 mantissa >>= shift 143 exp = -1023 + 2 144 } 145 // Round q using round-half-to-even. 146 exact = !haveRem 147 if mantissa&1 != 0 { 148 exact = false 149 if haveRem || mantissa&2 != 0 { 150 if mantissa++; mantissa >= 1<<54 { 151 // Complete rollover 11...1 => 100...0, so shift is safe 152 mantissa >>= 1 153 exp++ 154 } 155 } 156 } 157 mantissa >>= 1 // discard rounding bit. Mantissa now scaled by 2^53. 158 159 f = math.Ldexp(float64(mantissa), exp-53) 160 if math.IsInf(f, 0) { 161 exact = false 162 } 163 return 164 } 165 166 // Float64 returns the nearest float64 value for x and a bool indicating 167 // whether f represents x exactly. The sign of f always matches the sign 168 // of x, even if f == 0. 169 func (x *Rat) Float64() (f float64, exact bool) { 170 b := x.b.abs 171 if len(b) == 0 { 172 b = b.set(natOne) // materialize denominator 173 } 174 f, exact = quotToFloat(x.a.abs, b) 175 if x.a.neg { 176 f = -f 177 } 178 return 179 } 180 181 // SetFrac sets z to a/b and returns z. 182 func (z *Rat) SetFrac(a, b *Int) *Rat { 183 z.a.neg = a.neg != b.neg 184 babs := b.abs 185 if len(babs) == 0 { 186 panic("division by zero") 187 } 188 if &z.a == b || alias(z.a.abs, babs) { 189 babs = nat(nil).set(babs) // make a copy 190 } 191 z.a.abs = z.a.abs.set(a.abs) 192 z.b.abs = z.b.abs.set(babs) 193 return z.norm() 194 } 195 196 // SetFrac64 sets z to a/b and returns z. 197 func (z *Rat) SetFrac64(a, b int64) *Rat { 198 z.a.SetInt64(a) 199 if b == 0 { 200 panic("division by zero") 201 } 202 if b < 0 { 203 b = -b 204 z.a.neg = !z.a.neg 205 } 206 z.b.abs = z.b.abs.setUint64(uint64(b)) 207 return z.norm() 208 } 209 210 // SetInt sets z to x (by making a copy of x) and returns z. 211 func (z *Rat) SetInt(x *Int) *Rat { 212 z.a.Set(x) 213 z.b.abs = z.b.abs.make(0) 214 return z 215 } 216 217 // SetInt64 sets z to x and returns z. 218 func (z *Rat) SetInt64(x int64) *Rat { 219 z.a.SetInt64(x) 220 z.b.abs = z.b.abs.make(0) 221 return z 222 } 223 224 // Set sets z to x (by making a copy of x) and returns z. 225 func (z *Rat) Set(x *Rat) *Rat { 226 if z != x { 227 z.a.Set(&x.a) 228 z.b.Set(&x.b) 229 } 230 return z 231 } 232 233 // Abs sets z to |x| (the absolute value of x) and returns z. 234 func (z *Rat) Abs(x *Rat) *Rat { 235 z.Set(x) 236 z.a.neg = false 237 return z 238 } 239 240 // Neg sets z to -x and returns z. 241 func (z *Rat) Neg(x *Rat) *Rat { 242 z.Set(x) 243 z.a.neg = len(z.a.abs) > 0 && !z.a.neg // 0 has no sign 244 return z 245 } 246 247 // Inv sets z to 1/x and returns z. 248 func (z *Rat) Inv(x *Rat) *Rat { 249 if len(x.a.abs) == 0 { 250 panic("division by zero") 251 } 252 z.Set(x) 253 a := z.b.abs 254 if len(a) == 0 { 255 a = a.set(natOne) // materialize numerator 256 } 257 b := z.a.abs 258 if b.cmp(natOne) == 0 { 259 b = b.make(0) // normalize denominator 260 } 261 z.a.abs, z.b.abs = a, b // sign doesn't change 262 return z 263 } 264 265 // Sign returns: 266 // 267 // -1 if x < 0 268 // 0 if x == 0 269 // +1 if x > 0 270 // 271 func (x *Rat) Sign() int { 272 return x.a.Sign() 273 } 274 275 // IsInt returns true if the denominator of x is 1. 276 func (x *Rat) IsInt() bool { 277 return len(x.b.abs) == 0 || x.b.abs.cmp(natOne) == 0 278 } 279 280 // Num returns the numerator of x; it may be <= 0. 281 // The result is a reference to x's numerator; it 282 // may change if a new value is assigned to x, and vice versa. 283 // The sign of the numerator corresponds to the sign of x. 284 func (x *Rat) Num() *Int { 285 return &x.a 286 } 287 288 // Denom returns the denominator of x; it is always > 0. 289 // The result is a reference to x's denominator; it 290 // may change if a new value is assigned to x, and vice versa. 291 func (x *Rat) Denom() *Int { 292 x.b.neg = false // the result is always >= 0 293 if len(x.b.abs) == 0 { 294 x.b.abs = x.b.abs.set(natOne) // materialize denominator 295 } 296 return &x.b 297 } 298 299 func (z *Rat) norm() *Rat { 300 switch { 301 case len(z.a.abs) == 0: 302 // z == 0 - normalize sign and denominator 303 z.a.neg = false 304 z.b.abs = z.b.abs.make(0) 305 case len(z.b.abs) == 0: 306 // z is normalized int - nothing to do 307 case z.b.abs.cmp(natOne) == 0: 308 // z is int - normalize denominator 309 z.b.abs = z.b.abs.make(0) 310 default: 311 neg := z.a.neg 312 z.a.neg = false 313 z.b.neg = false 314 if f := NewInt(0).binaryGCD(&z.a, &z.b); f.Cmp(intOne) != 0 { 315 z.a.abs, _ = z.a.abs.div(nil, z.a.abs, f.abs) 316 z.b.abs, _ = z.b.abs.div(nil, z.b.abs, f.abs) 317 if z.b.abs.cmp(natOne) == 0 { 318 // z is int - normalize denominator 319 z.b.abs = z.b.abs.make(0) 320 } 321 } 322 z.a.neg = neg 323 } 324 return z 325 } 326 327 // mulDenom sets z to the denominator product x*y (by taking into 328 // account that 0 values for x or y must be interpreted as 1) and 329 // returns z. 330 func mulDenom(z, x, y nat) nat { 331 switch { 332 case len(x) == 0: 333 return z.set(y) 334 case len(y) == 0: 335 return z.set(x) 336 } 337 return z.mul(x, y) 338 } 339 340 // scaleDenom computes x*f. 341 // If f == 0 (zero value of denominator), the result is (a copy of) x. 342 func scaleDenom(x *Int, f nat) *Int { 343 var z Int 344 if len(f) == 0 { 345 return z.Set(x) 346 } 347 z.abs = z.abs.mul(x.abs, f) 348 z.neg = x.neg 349 return &z 350 } 351 352 // Cmp compares x and y and returns: 353 // 354 // -1 if x < y 355 // 0 if x == y 356 // +1 if x > y 357 // 358 func (x *Rat) Cmp(y *Rat) int { 359 return scaleDenom(&x.a, y.b.abs).Cmp(scaleDenom(&y.a, x.b.abs)) 360 } 361 362 // Add sets z to the sum x+y and returns z. 363 func (z *Rat) Add(x, y *Rat) *Rat { 364 a1 := scaleDenom(&x.a, y.b.abs) 365 a2 := scaleDenom(&y.a, x.b.abs) 366 z.a.Add(a1, a2) 367 z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs) 368 return z.norm() 369 } 370 371 // Sub sets z to the difference x-y and returns z. 372 func (z *Rat) Sub(x, y *Rat) *Rat { 373 a1 := scaleDenom(&x.a, y.b.abs) 374 a2 := scaleDenom(&y.a, x.b.abs) 375 z.a.Sub(a1, a2) 376 z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs) 377 return z.norm() 378 } 379 380 // Mul sets z to the product x*y and returns z. 381 func (z *Rat) Mul(x, y *Rat) *Rat { 382 z.a.Mul(&x.a, &y.a) 383 z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs) 384 return z.norm() 385 } 386 387 // Quo sets z to the quotient x/y and returns z. 388 // If y == 0, a division-by-zero run-time panic occurs. 389 func (z *Rat) Quo(x, y *Rat) *Rat { 390 if len(y.a.abs) == 0 { 391 panic("division by zero") 392 } 393 a := scaleDenom(&x.a, y.b.abs) 394 b := scaleDenom(&y.a, x.b.abs) 395 z.a.abs = a.abs 396 z.b.abs = b.abs 397 z.a.neg = a.neg != b.neg 398 return z.norm() 399 } 400 401 func ratTok(ch rune) bool { 402 return strings.IndexRune("+-/0123456789.eE", ch) >= 0 403 } 404 405 // Scan is a support routine for fmt.Scanner. It accepts the formats 406 // 'e', 'E', 'f', 'F', 'g', 'G', and 'v'. All formats are equivalent. 407 func (z *Rat) Scan(s fmt.ScanState, ch rune) error { 408 tok, err := s.Token(true, ratTok) 409 if err != nil { 410 return err 411 } 412 if strings.IndexRune("efgEFGv", ch) < 0 { 413 return errors.New("Rat.Scan: invalid verb") 414 } 415 if _, ok := z.SetString(string(tok)); !ok { 416 return errors.New("Rat.Scan: invalid syntax") 417 } 418 return nil 419 } 420 421 // SetString sets z to the value of s and returns z and a boolean indicating 422 // success. s can be given as a fraction "a/b" or as a floating-point number 423 // optionally followed by an exponent. If the operation failed, the value of 424 // z is undefined but the returned value is nil. 425 func (z *Rat) SetString(s string) (*Rat, bool) { 426 if len(s) == 0 { 427 return nil, false 428 } 429 430 // check for a quotient 431 sep := strings.Index(s, "/") 432 if sep >= 0 { 433 if _, ok := z.a.SetString(s[0:sep], 10); !ok { 434 return nil, false 435 } 436 s = s[sep+1:] 437 var err error 438 if z.b.abs, _, err = z.b.abs.scan(strings.NewReader(s), 10); err != nil { 439 return nil, false 440 } 441 return z.norm(), true 442 } 443 444 // check for a decimal point 445 sep = strings.Index(s, ".") 446 // check for an exponent 447 e := strings.IndexAny(s, "eE") 448 var exp Int 449 if e >= 0 { 450 if e < sep { 451 // The E must come after the decimal point. 452 return nil, false 453 } 454 if _, ok := exp.SetString(s[e+1:], 10); !ok { 455 return nil, false 456 } 457 s = s[0:e] 458 } 459 if sep >= 0 { 460 s = s[0:sep] + s[sep+1:] 461 exp.Sub(&exp, NewInt(int64(len(s)-sep))) 462 } 463 464 if _, ok := z.a.SetString(s, 10); !ok { 465 return nil, false 466 } 467 powTen := nat(nil).expNN(natTen, exp.abs, nil) 468 if exp.neg { 469 z.b.abs = powTen 470 z.norm() 471 } else { 472 z.a.abs = z.a.abs.mul(z.a.abs, powTen) 473 z.b.abs = z.b.abs.make(0) 474 } 475 476 return z, true 477 } 478 479 // String returns a string representation of z in the form "a/b" (even if b == 1). 480 func (x *Rat) String() string { 481 s := "/1" 482 if len(x.b.abs) != 0 { 483 s = "/" + x.b.abs.decimalString() 484 } 485 return x.a.String() + s 486 } 487 488 // RatString returns a string representation of z in the form "a/b" if b != 1, 489 // and in the form "a" if b == 1. 490 func (x *Rat) RatString() string { 491 if x.IsInt() { 492 return x.a.String() 493 } 494 return x.String() 495 } 496 497 // FloatString returns a string representation of z in decimal form with prec 498 // digits of precision after the decimal point and the last digit rounded. 499 func (x *Rat) FloatString(prec int) string { 500 if x.IsInt() { 501 s := x.a.String() 502 if prec > 0 { 503 s += "." + strings.Repeat("0", prec) 504 } 505 return s 506 } 507 // x.b.abs != 0 508 509 q, r := nat(nil).div(nat(nil), x.a.abs, x.b.abs) 510 511 p := natOne 512 if prec > 0 { 513 p = nat(nil).expNN(natTen, nat(nil).setUint64(uint64(prec)), nil) 514 } 515 516 r = r.mul(r, p) 517 r, r2 := r.div(nat(nil), r, x.b.abs) 518 519 // see if we need to round up 520 r2 = r2.add(r2, r2) 521 if x.b.abs.cmp(r2) <= 0 { 522 r = r.add(r, natOne) 523 if r.cmp(p) >= 0 { 524 q = nat(nil).add(q, natOne) 525 r = nat(nil).sub(r, p) 526 } 527 } 528 529 s := q.decimalString() 530 if x.a.neg { 531 s = "-" + s 532 } 533 534 if prec > 0 { 535 rs := r.decimalString() 536 leadingZeros := prec - len(rs) 537 s += "." + strings.Repeat("0", leadingZeros) + rs 538 } 539 540 return s 541 } 542 543 // Gob codec version. Permits backward-compatible changes to the encoding. 544 const ratGobVersion byte = 1 545 546 // GobEncode implements the gob.GobEncoder interface. 547 func (x *Rat) GobEncode() ([]byte, error) { 548 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) 549 i := x.b.abs.bytes(buf) 550 j := x.a.abs.bytes(buf[0:i]) 551 n := i - j 552 if int(uint32(n)) != n { 553 // this should never happen 554 return nil, errors.New("Rat.GobEncode: numerator too large") 555 } 556 binary.BigEndian.PutUint32(buf[j-4:j], uint32(n)) 557 j -= 1 + 4 558 b := ratGobVersion << 1 // make space for sign bit 559 if x.a.neg { 560 b |= 1 561 } 562 buf[j] = b 563 return buf[j:], nil 564 } 565 566 // GobDecode implements the gob.GobDecoder interface. 567 func (z *Rat) GobDecode(buf []byte) error { 568 if len(buf) == 0 { 569 return errors.New("Rat.GobDecode: no data") 570 } 571 b := buf[0] 572 if b>>1 != ratGobVersion { 573 return errors.New(fmt.Sprintf("Rat.GobDecode: encoding version %d not supported", b>>1)) 574 } 575 const j = 1 + 4 576 i := j + binary.BigEndian.Uint32(buf[j-4:j]) 577 z.a.neg = b&1 != 0 578 z.a.abs = z.a.abs.setBytes(buf[j:i]) 579 z.b.abs = z.b.abs.setBytes(buf[i:]) 580 return nil 581 }