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  }