github.com/richardwilkes/toolbox@v1.121.0/xmath/num/uint128.go (about) 1 // Copyright (c) 2016-2024 by Richard A. Wilkes. All rights reserved. 2 // 3 // This Source Code Form is subject to the terms of the Mozilla Public 4 // License, version 2.0. If a copy of the MPL was not distributed with 5 // this file, You can obtain one at http://mozilla.org/MPL/2.0/. 6 // 7 // This Source Code Form is "Incompatible With Secondary Licenses", as 8 // defined by the Mozilla Public License, version 2.0. 9 10 package num 11 12 import ( 13 "errors" 14 "fmt" 15 "math" 16 "math/big" 17 "math/bits" 18 "strconv" 19 "strings" 20 21 "github.com/richardwilkes/toolbox/errs" 22 ) 23 24 const ( 25 divBinaryShiftThreshold = 16 26 divByZero = "divide by zero" 27 bit32 = uint64(1) << 32 28 ) 29 30 // MaxUint128 is the maximum value representable by a Uint128. 31 var MaxUint128 = Uint128{hi: math.MaxUint64, lo: math.MaxUint64} 32 33 var ( 34 intSize = 32 << (^uint(0) >> 63) 35 maxUint64Float = float64(math.MaxUint64) 36 maxRepresentableUint64Float = math.Nextafter(maxUint64Float, 0) 37 maxRepresentableUint128Float = math.Nextafter(float64(340282366920938463463374607431768211455), 0) 38 wrapUint64Float = float64(math.MaxUint64) + 1 39 errNoFloat64 = errors.New("no float64 conversion for json/yaml") 40 errDoesNotFitInInt64 = errors.New("does not fit in int64") 41 ) 42 43 // RandomSource defines the method required of a source of random bits. This is a subset of the rand.Source64 interface. 44 type RandomSource interface { 45 Uint64() uint64 46 } 47 48 // Uint128 represents an unsigned 128-bit integer. 49 type Uint128 struct { 50 hi uint64 51 lo uint64 52 } 53 54 // Uint128From64 creates a Uint128 from a uint64 value. 55 func Uint128From64(v uint64) Uint128 { 56 return Uint128{lo: v} 57 } 58 59 // Uint128FromFloat64 creates a Uint128 from a float64 value. 60 func Uint128FromFloat64(f float64) Uint128 { 61 switch { 62 case f <= 0 || f != f: // <= 0 or NaN 63 return Uint128{} 64 case f <= maxRepresentableUint64Float: 65 return Uint128{lo: uint64(f)} 66 case f <= maxRepresentableUint128Float: 67 return Uint128{ 68 hi: uint64(f / wrapUint64Float), 69 lo: uint64(math.Mod(f, wrapUint64Float)), 70 } 71 default: 72 return MaxUint128 73 } 74 } 75 76 // Uint128FromBigInt creates a Uint128 from a big.Int. 77 func Uint128FromBigInt(v *big.Int) Uint128 { 78 if v.Sign() < 0 { 79 return Uint128{} 80 } 81 words := v.Bits() 82 switch len(words) { 83 case 0: 84 return Uint128{} 85 case 1: 86 return Uint128{lo: uint64(words[0])} 87 case 2: 88 if intSize == 64 { 89 return Uint128{ 90 hi: uint64(words[1]), 91 lo: uint64(words[0]), 92 } 93 } 94 return Uint128{lo: (uint64(words[1]) << 32) | (uint64(words[0]))} 95 case 3: 96 if intSize == 64 { 97 return MaxUint128 98 } 99 return Uint128{ 100 hi: uint64(words[2]), 101 lo: (uint64(words[1]) << 32) | (uint64(words[0])), 102 } 103 case 4: 104 if intSize == 64 { 105 return MaxUint128 106 } 107 return Uint128{ 108 hi: (uint64(words[3]) << 32) | (uint64(words[2])), 109 lo: (uint64(words[1]) << 32) | (uint64(words[0])), 110 } 111 default: 112 return MaxUint128 113 } 114 } 115 116 // Uint128FromString creates a Uint128 from a string. 117 func Uint128FromString(s string) (Uint128, error) { 118 b, err := parseToBigInt(s) 119 if err != nil { 120 return Uint128{}, err 121 } 122 return Uint128FromBigInt(b), nil 123 } 124 125 func parseToBigInt(s string) (*big.Int, error) { 126 var b *big.Int 127 var ok bool 128 if strings.ContainsAny(s, "Ee") { 129 // Given a floating-point value with an exponent, which technically isn't valid input, but we'll try to convert 130 // it anyway. 131 var f *big.Float 132 f, ok = new(big.Float).SetString(s) 133 if ok && !f.IsInt() { 134 ok = false 135 } 136 if ok { 137 b, _ = f.Int(nil) 138 } 139 } else { 140 b, ok = new(big.Int).SetString(s, 0) 141 } 142 if !ok { 143 return nil, errs.Newf("invalid input: %s", s) 144 } 145 return b, nil 146 } 147 148 // Uint128FromStringNoCheck creates a Uint128 from a string. Unlike Uint128FromString, this allows any string as input. 149 func Uint128FromStringNoCheck(s string) Uint128 { 150 out, _ := Uint128FromString(s) //nolint:errcheck // Failure results in 0 151 return out 152 } 153 154 // Uint128FromComponents creates a Uint128 from two uint64 values representing the high and low bits. 155 func Uint128FromComponents(high, low uint64) Uint128 { 156 return Uint128{hi: high, lo: low} 157 } 158 159 // Uint128FromRand generates an unsigned 128-bit random integer. 160 func Uint128FromRand(source RandomSource) Uint128 { 161 return Uint128{hi: source.Uint64(), lo: source.Uint64()} 162 } 163 164 // Components returns the two uint64 values representing the high and low bits. 165 func (u Uint128) Components() (high, low uint64) { 166 return u.hi, u.lo 167 } 168 169 // IsZero returns true if the value is 0. 170 func (u Uint128) IsZero() bool { 171 return u.hi|u.lo == 0 172 } 173 174 // ToBigInt stores the Uint128's value into the specified big.Int. 175 func (u Uint128) ToBigInt(b *big.Int) { 176 words := b.Bits() 177 if intSize == 64 { 178 if len(words) < 2 { 179 words = append(words, make([]big.Word, 2-len(words))...) 180 } 181 words = words[:2] 182 words[0] = big.Word(u.lo) 183 words[1] = big.Word(u.hi) 184 } else { 185 if len(words) < 4 { 186 words = append(words, make([]big.Word, 4-len(words))...) 187 } 188 words = words[:4] 189 words[0] = big.Word(u.lo & 0xFFFFFFFF) 190 words[1] = big.Word(u.lo >> 32) 191 words[2] = big.Word(u.hi & 0xFFFFFFFF) 192 words[3] = big.Word(u.hi >> 32) 193 } 194 b.SetBits(words) 195 } 196 197 // AsBigInt returns the Uint128 as a big.Int. 198 func (u Uint128) AsBigInt() *big.Int { 199 var b big.Int 200 u.ToBigInt(&b) 201 return &b 202 } 203 204 // AsBigFloat returns the Uint128 as a big.Float. 205 func (u Uint128) AsBigFloat() *big.Float { 206 return new(big.Float).SetInt(u.AsBigInt()) 207 } 208 209 // AsFloat64 returns the Uint128 as a float64. 210 func (u Uint128) AsFloat64() float64 { 211 if u.hi == 0 { 212 if u.lo == 0 { 213 return 0 214 } 215 return float64(u.lo) 216 } 217 return (float64(u.hi) * wrapUint64Float) + float64(u.lo) 218 } 219 220 // IsInt128 returns true if this value can be represented as an Int128 without any loss. 221 func (u Uint128) IsInt128() bool { 222 return u.hi&signBit == 0 223 } 224 225 // AsInt128 returns the Uint128 as an Int128. 226 func (u Uint128) AsInt128() Int128 { 227 return Int128(u) 228 } 229 230 // IsUint64 returns true if this value can be represented as a uint64 without any loss. 231 func (u Uint128) IsUint64() bool { 232 return u.hi == 0 233 } 234 235 // AsUint64 returns the Uint128 as a uint64. 236 func (u Uint128) AsUint64() uint64 { 237 return u.lo 238 } 239 240 // Add returns u + n. 241 func (u Uint128) Add(n Uint128) Uint128 { 242 lo, carry := bits.Add64(u.lo, n.lo, 0) 243 hi, _ := bits.Add64(u.hi, n.hi, carry) 244 return Uint128{ 245 hi: hi, 246 lo: lo, 247 } 248 } 249 250 // Add64 returns u + n. 251 func (u Uint128) Add64(n uint64) Uint128 { 252 lo, carry := bits.Add64(u.lo, n, 0) 253 return Uint128{ 254 hi: u.hi + carry, 255 lo: lo, 256 } 257 } 258 259 // Sub returns u - n. 260 func (u Uint128) Sub(n Uint128) Uint128 { 261 lo, borrow := bits.Sub64(u.lo, n.lo, 0) 262 hi, _ := bits.Sub64(u.hi, n.hi, borrow) 263 return Uint128{ 264 hi: hi, 265 lo: lo, 266 } 267 } 268 269 // Sub64 returns u - n. 270 func (u Uint128) Sub64(n uint64) Uint128 { 271 lo, borrow := bits.Sub64(u.lo, n, 0) 272 return Uint128{ 273 hi: u.hi - borrow, 274 lo: lo, 275 } 276 } 277 278 // Inc returns u + 1. 279 func (u Uint128) Inc() Uint128 { 280 lo, carry := bits.Add64(u.lo, 1, 0) 281 return Uint128{ 282 hi: u.hi + carry, 283 lo: lo, 284 } 285 } 286 287 // Dec returns u - 1. 288 func (u Uint128) Dec() Uint128 { 289 lo, borrow := bits.Sub64(u.lo, 1, 0) 290 return Uint128{ 291 hi: u.hi - borrow, 292 lo: lo, 293 } 294 } 295 296 // Cmp returns 1 if u > n, 0 if u == n, and -1 if u < n. 297 func (u Uint128) Cmp(n Uint128) int { 298 switch { 299 case u.hi == n.hi: 300 if u.lo > n.lo { 301 return 1 302 } else if u.lo < n.lo { 303 return -1 304 } 305 case u.hi > n.hi: 306 return 1 307 case u.hi < n.hi: 308 return -1 309 } 310 return 0 311 } 312 313 // Cmp64 returns 1 if u > n, 0 if u == n, and -1 if u < n. 314 func (u Uint128) Cmp64(n uint64) int { 315 switch { 316 case u.hi > 0 || u.lo > n: 317 return 1 318 case u.lo < n: 319 return -1 320 default: 321 return 0 322 } 323 } 324 325 // GreaterThan returns true if u > n. 326 func (u Uint128) GreaterThan(n Uint128) bool { 327 return u.hi > n.hi || (u.hi == n.hi && u.lo > n.lo) 328 } 329 330 // GreaterThan64 returns true if u > n. 331 func (u Uint128) GreaterThan64(n uint64) bool { 332 return u.hi > 0 || u.lo > n 333 } 334 335 // GreaterThanOrEqual returns true if u >= n. 336 func (u Uint128) GreaterThanOrEqual(n Uint128) bool { 337 return u.hi > n.hi || (u.hi == n.hi && u.lo >= n.lo) 338 } 339 340 // GreaterThanOrEqual64 returns true if u >= n. 341 func (u Uint128) GreaterThanOrEqual64(n uint64) bool { 342 return u.hi > 0 || u.lo >= n 343 } 344 345 // Equal returns true if u == n. 346 func (u Uint128) Equal(n Uint128) bool { 347 return u.hi == n.hi && u.lo == n.lo 348 } 349 350 // Equal64 returns true if u == n. 351 func (u Uint128) Equal64(n uint64) bool { 352 return u.hi == 0 && u.lo == n 353 } 354 355 // LessThan returns true if u < n. 356 func (u Uint128) LessThan(n Uint128) bool { 357 return u.hi < n.hi || (u.hi == n.hi && u.lo < n.lo) 358 } 359 360 // LessThan64 returns true if u < n. 361 func (u Uint128) LessThan64(n uint64) bool { 362 return u.hi == 0 && u.lo < n 363 } 364 365 // LessThanOrEqual returns true if u <= n. 366 func (u Uint128) LessThanOrEqual(n Uint128) bool { 367 return u.hi < n.hi || (u.hi == n.hi && u.lo <= n.lo) 368 } 369 370 // LessThanOrEqual64 returns true if u <= n. 371 func (u Uint128) LessThanOrEqual64(n uint64) bool { 372 return u.hi == 0 && u.lo <= n 373 } 374 375 // BitLen returns the length of the absolute value of u in bits. The bit length of 0 is 0. 376 func (u Uint128) BitLen() int { 377 if u.hi != 0 { 378 return bits.Len64(u.hi) + 64 379 } 380 return bits.Len64(u.lo) 381 } 382 383 // OnesCount returns the number of one bits ("population count") in u. 384 func (u Uint128) OnesCount() int { 385 if u.hi != 0 { 386 return bits.OnesCount64(u.hi) + 64 387 } 388 return bits.OnesCount64(u.lo) 389 } 390 391 // Bit returns the value of the i'th bit of x. That is, it returns (x>>i)&1. If the bit index is less than 0 or greater 392 // than 127, zero will be returned. 393 func (u Uint128) Bit(i int) uint { 394 switch { 395 case i < 0 || i > 127: 396 return 0 397 case i < 64: 398 return uint((u.lo >> uint(i)) & 1) 399 default: 400 return uint((u.hi >> uint(i-64)) & 1) 401 } 402 } 403 404 // SetBit returns a Uint128 with u's i'th bit set to b (0 or 1). Values of b that are not 0 will be treated as 1. If the 405 // bit index is less than 0 or greater than 127, nothing will happen. 406 func (u Uint128) SetBit(i int, b uint) Uint128 { 407 if i < 0 || i > 127 { 408 return u 409 } 410 if b == 0 { 411 if i >= 64 { 412 u.hi &^= 1 << uint(i-64) 413 } else { 414 u.lo &^= 1 << uint(i) 415 } 416 } else { 417 if i >= 64 { 418 u.hi |= 1 << uint(i-64) 419 } else { 420 u.lo |= 1 << uint(i) 421 } 422 } 423 return u 424 } 425 426 // Not returns ^u. 427 func (u Uint128) Not() Uint128 { 428 return Uint128{ 429 hi: ^u.hi, 430 lo: ^u.lo, 431 } 432 } 433 434 // And returns u & n. 435 func (u Uint128) And(n Uint128) Uint128 { 436 return Uint128{ 437 hi: u.hi & n.hi, 438 lo: u.lo & n.lo, 439 } 440 } 441 442 // And64 returns u & n. 443 func (u Uint128) And64(n uint64) Uint128 { 444 return Uint128{lo: u.lo & n} 445 } 446 447 // AndNot returns u &^ n. 448 func (u Uint128) AndNot(n Uint128) Uint128 { 449 return Uint128{ 450 hi: u.hi &^ n.hi, 451 lo: u.lo &^ n.lo, 452 } 453 } 454 455 // AndNot64 returns u &^ n. 456 func (u Uint128) AndNot64(n Uint128) Uint128 { 457 return Uint128{ 458 hi: u.hi, 459 lo: u.lo &^ n.lo, 460 } 461 } 462 463 // Or returns u | n. 464 func (u Uint128) Or(n Uint128) Uint128 { 465 return Uint128{ 466 hi: u.hi | n.hi, 467 lo: u.lo | n.lo, 468 } 469 } 470 471 // Or64 returns u | n. 472 func (u Uint128) Or64(n uint64) Uint128 { 473 return Uint128{ 474 hi: u.hi, 475 lo: u.lo | n, 476 } 477 } 478 479 // Xor returns u ^ n. 480 func (u Uint128) Xor(n Uint128) Uint128 { 481 return Uint128{ 482 hi: u.hi ^ n.hi, 483 lo: u.lo ^ n.lo, 484 } 485 } 486 487 // Xor64 returns u ^ n. 488 func (u Uint128) Xor64(n uint64) Uint128 { 489 return Uint128{ 490 hi: u.hi, 491 lo: u.lo ^ n, 492 } 493 } 494 495 // LeadingZeros returns the number of leading bits set to 0. 496 func (u Uint128) LeadingZeros() uint { 497 if u.hi == 0 { 498 return uint(bits.LeadingZeros64(u.lo)) + 64 499 } 500 return uint(bits.LeadingZeros64(u.hi)) 501 } 502 503 // TrailingZeros returns the number of trailing bits set to 0. 504 func (u Uint128) TrailingZeros() uint { 505 if u.lo == 0 { 506 return uint(bits.TrailingZeros64(u.hi)) + 64 507 } 508 return uint(bits.TrailingZeros64(u.lo)) 509 } 510 511 // LeftShift returns u << n. 512 func (u Uint128) LeftShift(n uint) Uint128 { 513 switch { 514 case n == 0: 515 case n > 64: 516 u.hi = u.lo << (n - 64) 517 u.lo = 0 518 case n < 64: 519 u.hi = (u.hi << n) | (u.lo >> (64 - n)) 520 u.lo <<= n 521 default: 522 u.hi = u.lo 523 u.lo = 0 524 } 525 return u 526 } 527 528 // RightShift returns u >> n. 529 func (u Uint128) RightShift(n uint) Uint128 { 530 switch { 531 case n == 0: 532 case n > 64: 533 u.lo = u.hi >> (n - 64) 534 u.hi = 0 535 case n < 64: 536 u.lo = (u.lo >> n) | (u.hi << (64 - n)) 537 u.hi >>= n 538 default: 539 u.lo = u.hi 540 u.hi = 0 541 } 542 return u 543 } 544 545 // Mul returns u * n. 546 func (u Uint128) Mul(n Uint128) Uint128 { 547 hi, lo := bits.Mul64(u.lo, n.lo) 548 return Uint128{ 549 hi: hi + u.hi*n.lo + u.lo*n.hi, 550 lo: lo, 551 } 552 } 553 554 // Mul64 returns u * n. 555 func (u Uint128) Mul64(n uint64) (dest Uint128) { 556 x0 := u.lo & 0xFFFFFFFF 557 x1 := u.lo >> 32 558 y0 := n & 0xFFFFFFFF 559 y1 := n >> 32 560 t := x1*y0 + (x0*y0)>>32 561 return Uint128{ 562 hi: (x1 * y1) + (t >> 32) + (((t & 0xFFFFFFFF) + (x0 * y1)) >> 32) + u.hi*n, 563 lo: u.lo * n, 564 } 565 } 566 567 // Div returns u / n. If n == 0, a divide by zero panic will occur. 568 func (u Uint128) Div(n Uint128) Uint128 { 569 var nLoLeading0, nHiLeading0, nLeading0 uint 570 if n.hi == 0 { 571 if n.lo == 0 { 572 panic(divByZero) 573 } 574 if n.lo == 1 { // divide by 1 575 return u 576 } 577 if u.hi == 0 { // 64-bit division only 578 u.lo /= n.lo 579 return u 580 } 581 nLoLeading0 = uint(bits.LeadingZeros64(n.lo)) 582 nHiLeading0 = 64 583 nLeading0 = nLoLeading0 + 64 584 } else { 585 nHiLeading0 = uint(bits.LeadingZeros64(n.hi)) 586 nLeading0 = nHiLeading0 587 } 588 nTrailing0 := n.TrailingZeros() 589 if (nLeading0 + nTrailing0) == 127 { // Only one bit set in divisor, so use right shift 590 return u.RightShift(nTrailing0) 591 } 592 if cmp := u.Cmp(n); cmp < 0 { 593 return Uint128{} // nothing but remainder 594 } else if cmp == 0 { // division by same value 595 return Uint128{lo: 1} 596 } 597 uLeading0 := u.LeadingZeros() 598 if nLeading0-uLeading0 > divBinaryShiftThreshold { 599 q, _ := u.divmod128by128(n, nHiLeading0, nLoLeading0) 600 return q 601 } 602 q, _ := u.divmod128bin(n, uLeading0, nLeading0) 603 return q 604 } 605 606 // Div64 returns u / n. If n == 0, a divide by zero panic will occur. 607 func (u Uint128) Div64(n uint64) Uint128 { 608 if n == 0 { 609 panic(divByZero) 610 } 611 if n == 1 { 612 return u 613 } 614 if u.hi == 0 { // 64-bit division only 615 u.lo /= n 616 return u 617 } 618 nLoLeading0 := uint(bits.LeadingZeros64(n)) 619 nLeading0 := nLoLeading0 + 64 620 nTrailing0 := uint(bits.TrailingZeros64(n)) 621 if nLeading0+nTrailing0 == 127 { // Only one bit set in divisor, so use right shift 622 return u.RightShift(nTrailing0) 623 } 624 if cmp := u.Cmp64(n); cmp < 0 { 625 return Uint128{} // nothing but remainder 626 } else if cmp == 0 { // division by same value 627 return Uint128{lo: 1} 628 } 629 uLeading0 := u.LeadingZeros() 630 if nLeading0-uLeading0 > divBinaryShiftThreshold { 631 if u.hi < n { 632 u.lo, _ = u.divmod128by64(n, nLoLeading0) 633 u.hi = 0 634 } else { 635 hi := u.hi / n 636 u.hi %= n 637 u.lo, _ = u.divmod128by64(n, nLoLeading0) 638 u.hi = hi 639 } 640 return u 641 } 642 q, _ := u.divmod128bin(Uint128{lo: n}, uLeading0, nLeading0) 643 return q 644 } 645 646 // DivMod returns both the result of u / n as well u % n. If n == 0, a divide by zero panic will occur. 647 func (u Uint128) DivMod(n Uint128) (q, r Uint128) { 648 var nLoLeading0, nHiLeading0, nLeading0 uint 649 if n.hi == 0 { 650 if n.lo == 0 { 651 panic(divByZero) 652 } 653 if n.lo == 1 { // divide by 1 654 return u, r 655 } 656 if u.hi == 0 { // 64-bit division only 657 q.lo = u.lo / n.lo 658 r.lo = u.lo % n.lo 659 return q, r 660 } 661 nLoLeading0 = uint(bits.LeadingZeros64(n.lo)) 662 nHiLeading0 = 64 663 nLeading0 = nLoLeading0 + 64 664 } else { 665 nHiLeading0 = uint(bits.LeadingZeros64(n.hi)) 666 nLeading0 = nHiLeading0 667 } 668 nTrailing0 := n.TrailingZeros() 669 if (nLeading0 + nTrailing0) == 127 { // Only one bit set in divisor, so use right shift 670 q = u.RightShift(nTrailing0) 671 r = n.Dec().And(u) 672 return q, r 673 } 674 if cmp := u.Cmp(n); cmp < 0 { 675 return q, u // nothing but remainder 676 } else if cmp == 0 { // division by same value 677 q.lo = 1 678 return q, r 679 } 680 uLeading0 := u.LeadingZeros() 681 if nLeading0-uLeading0 > divBinaryShiftThreshold { 682 return u.divmod128by128(n, nHiLeading0, nLoLeading0) 683 } 684 return u.divmod128bin(n, uLeading0, nLeading0) 685 } 686 687 // DivMod64 returns both the result of u / n as well u % n. If n == 0, a divide by zero panic will occur. 688 func (u Uint128) DivMod64(n uint64) (q, r Uint128) { 689 if n == 0 { 690 panic(divByZero) 691 } 692 if n == 1 { 693 return u, r 694 } 695 if u.hi == 0 { // 64-bit division only 696 q.lo = u.lo / n 697 r.lo = u.lo % n 698 return q, r 699 } 700 nLoLeading0 := uint(bits.LeadingZeros64(n)) 701 nLeading0 := nLoLeading0 + 64 702 nTrailing0 := uint(bits.TrailingZeros64(n)) 703 if nLeading0+nTrailing0 == 127 { // Only one bit set in divisor, so use right shift 704 q = u.RightShift(nTrailing0) 705 r = u.And64(n - 1) 706 return q, r 707 } 708 if cmp := u.Cmp64(n); cmp < 0 { 709 return q, u // nothing but remainder 710 } else if cmp == 0 { // division by same value 711 q.lo = 1 712 return q, r 713 } 714 uLeading0 := u.LeadingZeros() 715 if nLeading0-uLeading0 > divBinaryShiftThreshold { 716 if u.hi < n { 717 q.lo, r.lo = u.divmod128by64(n, nLoLeading0) 718 } else { 719 q.hi = u.hi / n 720 u.hi %= n 721 q.lo, r.lo = u.divmod128by64(n, nLoLeading0) 722 } 723 return q, r 724 } 725 return u.divmod128bin(Uint128{lo: n}, uLeading0, nLeading0) 726 } 727 728 // Mod returns u % n. If n == 0, a divide by zero panic will occur. 729 func (u Uint128) Mod(n Uint128) Uint128 { 730 var nLoLeading0, nHiLeading0, nLeading0 uint 731 if n.hi == 0 { 732 if n.lo == 0 { 733 panic(divByZero) 734 } 735 if n.lo == 1 { // divide by 1 736 return Uint128{} 737 } 738 if u.hi == 0 { // 64-bit division only 739 u.lo %= n.lo 740 return u 741 } 742 nLoLeading0 = uint(bits.LeadingZeros64(n.lo)) 743 nHiLeading0 = 64 744 nLeading0 = nLoLeading0 + 64 745 } else { 746 nHiLeading0 = uint(bits.LeadingZeros64(n.hi)) 747 nLeading0 = nHiLeading0 748 } 749 nTrailing0 := n.TrailingZeros() 750 if (nLeading0 + nTrailing0) == 127 { // Only one bit set in divisor, so use right shift 751 return n.Dec().And(u) 752 } 753 if cmp := u.Cmp(n); cmp < 0 { 754 return u // nothing but remainder 755 } else if cmp == 0 { // division by same value 756 return Uint128{} 757 } 758 uLeading0 := u.LeadingZeros() 759 if nLeading0-uLeading0 > divBinaryShiftThreshold { 760 _, r := u.divmod128by128(n, nHiLeading0, nLoLeading0) 761 return r 762 } 763 _, r := u.divmod128bin(n, uLeading0, nLeading0) 764 return r 765 } 766 767 // Mod64 returns u % n. If n == 0, a divide by zero panic will occur. 768 func (u Uint128) Mod64(n uint64) Uint128 { 769 if n == 0 { 770 panic(divByZero) 771 } 772 if n == 1 { 773 return Uint128{} 774 } 775 if u.hi == 0 { // 64-bit division only 776 u.lo %= n 777 return u 778 } 779 nLoLeading0 := uint(bits.LeadingZeros64(n)) 780 nLeading0 := nLoLeading0 + 64 781 nTrailing0 := uint(bits.TrailingZeros64(n)) 782 if nLeading0+nTrailing0 == 127 { // Only one bit set in divisor, so use right shift 783 return u.And64(n - 1) 784 } 785 if cmp := u.Cmp64(n); cmp < 0 { 786 return u // nothing but remainder 787 } else if cmp == 0 { // division by same value 788 return Uint128{} 789 } 790 uLeading0 := u.LeadingZeros() 791 if nLeading0-uLeading0 > divBinaryShiftThreshold { 792 if u.hi >= n { 793 u.hi %= n 794 } 795 _, r := u.divmod128by64(n, nLoLeading0) 796 return Uint128{lo: r} 797 } 798 _, r := u.divmod128bin(Uint128{lo: n}, uLeading0, nLeading0) 799 return r 800 } 801 802 // divmod128by64 was adapted from https://www.codeproject.com/Tips/785014/UInt-Division-Modulus 803 func (u Uint128) divmod128by64(n uint64, nLeading0 uint) (q, r uint64) { 804 n <<= nLeading0 805 vn1 := n >> 32 806 vn0 := n & 0xffffffff 807 if nLeading0 > 0 { 808 u.hi = (u.hi << nLeading0) | (u.lo >> (64 - nLeading0)) 809 u.lo <<= nLeading0 810 } 811 un1 := u.lo >> 32 812 un0 := u.lo & 0xffffffff 813 q1 := u.hi / vn1 814 rhat := u.hi % vn1 815 left := q1 * vn0 816 right := (rhat << 32) + un1 817 loop1: 818 if (q1 >= bit32) || (left > right) { 819 q1-- 820 rhat += vn1 821 if rhat < bit32 { 822 left -= vn0 823 right = (rhat << 32) | un1 824 goto loop1 825 } 826 } 827 un21 := (u.hi << 32) + (un1 - (q1 * n)) 828 q0 := un21 / vn1 829 rhat = un21 % vn1 830 left = q0 * vn0 831 right = (rhat << 32) | un0 832 loop2: 833 if (q0 >= bit32) || (left > right) { 834 q0-- 835 rhat += vn1 836 if rhat < bit32 { 837 left -= vn0 838 right = (rhat << 32) | un0 839 goto loop2 840 } 841 } 842 return (q1 << 32) | q0, ((un21 << 32) + (un0 - (q0 * n))) >> nLeading0 843 } 844 845 // divmod128by128 was adapted from https://www.codeproject.com/Tips/785014/UInt-Division-Modulus 846 func (u Uint128) divmod128by128(n Uint128, nHiLeading0, nLoLeading0 uint) (q, r Uint128) { 847 if n.hi == 0 { 848 if u.hi < n.lo { 849 q.lo, r.lo = u.divmod128by64(n.lo, nLoLeading0) 850 return q, r 851 } 852 q.hi = u.hi / n.lo 853 u.hi %= n.lo 854 q.lo, r.lo = u.divmod128by64(n.lo, nLoLeading0) 855 r.hi = 0 856 return q, r 857 } 858 q.lo, _ = u.RightShift(1).divmod128by64(n.LeftShift(nHiLeading0).hi, nLoLeading0) 859 q.lo >>= 63 - nHiLeading0 860 if q.lo != 0 { 861 q.lo-- 862 } 863 r = u.Sub(q.Mul(n)) 864 if r.Cmp(n) >= 0 { 865 q = q.Inc() 866 r = r.Sub(n) 867 } 868 return q, r 869 } 870 871 // divmod128bin was adapted from https://www.codeproject.com/Tips/785014/UInt-Division-Modulus 872 func (u Uint128) divmod128bin(n Uint128, uLeading0, byLeading0 uint) (q, r Uint128) { 873 shift := int(byLeading0 - uLeading0) 874 n = n.LeftShift(uint(shift)) 875 for { 876 if u.GreaterThanOrEqual(n) { 877 //goland:noinspection GoAssignmentToReceiver 878 u = u.Sub(n) 879 q.lo |= 1 880 } 881 if shift <= 0 { 882 break 883 } 884 n = n.RightShift(1) 885 q = q.LeftShift(1) 886 shift-- 887 } 888 return q, u 889 } 890 891 // String implements fmt.Stringer. 892 func (u Uint128) String() string { 893 if u.hi == 0 { 894 if u.lo == 0 { 895 return "0" 896 } 897 return strconv.FormatUint(u.lo, 10) 898 } 899 return u.AsBigInt().String() 900 } 901 902 // Format implements fmt.Formatter. 903 func (u Uint128) Format(s fmt.State, c rune) { 904 u.AsBigInt().Format(s, c) 905 } 906 907 // Scan implements fmt.Scanner. 908 func (u *Uint128) Scan(state fmt.ScanState, _ rune) error { 909 t, err := state.Token(true, nil) 910 if err != nil { 911 return errs.Wrap(err) 912 } 913 var v Uint128 914 if v, err = Uint128FromString(string(t)); err != nil { 915 return errs.Wrap(err) 916 } 917 *u = v 918 return nil 919 } 920 921 // MarshalText implements encoding.TextMarshaler. 922 func (u Uint128) MarshalText() ([]byte, error) { 923 return []byte(u.String()), nil 924 } 925 926 // UnmarshalText implements encoding.TextUnmarshaler. 927 func (u *Uint128) UnmarshalText(text []byte) error { 928 v, err := Uint128FromString(string(text)) 929 if err != nil { 930 return err 931 } 932 *u = v 933 return nil 934 } 935 936 // Float64 implements json.Number. Intentionally always returns an error, as we never want to emit floating point values 937 // into json for Uint128. 938 func (u Uint128) Float64() (float64, error) { 939 return 0, errNoFloat64 940 } 941 942 // Int64 implements json.Number. 943 func (u Uint128) Int64() (int64, error) { 944 if u.IsInt128() { 945 i128 := Int128(u) 946 if i128.IsInt64() { 947 return i128.AsInt64(), nil 948 } 949 } 950 return 0, errDoesNotFitInInt64 951 } 952 953 // MarshalJSON implements json.Marshaler. 954 func (u Uint128) MarshalJSON() ([]byte, error) { 955 return []byte(u.String()), nil 956 } 957 958 // UnmarshalJSON implements json.Unmarshaler. 959 func (u *Uint128) UnmarshalJSON(in []byte) error { 960 v, err := Uint128FromString(string(in)) 961 if err != nil { 962 return err 963 } 964 *u = v 965 return nil 966 } 967 968 // MarshalYAML implements yaml.Marshaler. 969 func (u Uint128) MarshalYAML() (any, error) { 970 return u.String(), nil 971 } 972 973 // UnmarshalYAML implements yaml.Unmarshaler. 974 func (u *Uint128) UnmarshalYAML(unmarshal func(any) error) error { 975 var str string 976 if err := unmarshal(&str); err != nil { 977 return err 978 } 979 v, err := Uint128FromString(str) 980 if err != nil { 981 return err 982 } 983 *u = v 984 return nil 985 }