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