github.com/0chain/gosdk@v1.17.11/zboxcore/zboxutil/uint128.go (about)

     1  package zboxutil
     2  
     3  import "math/bits"
     4  
     5  type Uint128 struct {
     6  	High uint64
     7  	Low  uint64
     8  }
     9  
    10  func NewUint128(x uint64) Uint128 {
    11  	return Uint128{Low: x}
    12  }
    13  
    14  // Add returns x+y.
    15  func (x Uint128) Add(y Uint128) Uint128 {
    16  	Low, carry := bits.Add64(x.Low, y.Low, 0)
    17  	High, carry := bits.Add64(x.High, y.High, carry)
    18  	if carry != 0 {
    19  		panic("overfLow")
    20  	}
    21  	return Uint128{High, Low}
    22  }
    23  
    24  // Add64 returns x+y.
    25  func (x Uint128) Add64(y uint64) Uint128 {
    26  	Low, carry := bits.Add64(x.Low, y, 0)
    27  	High, carry := bits.Add64(x.High, 0, carry)
    28  	if carry != 0 {
    29  		panic("overfLow")
    30  	}
    31  	return Uint128{High, Low}
    32  }
    33  
    34  // Sub returns x-y.
    35  func (x Uint128) Sub(y Uint128) Uint128 {
    36  	Low, borrow := bits.Sub64(x.Low, y.Low, 0)
    37  	High, _ := bits.Sub64(x.High, y.High, borrow)
    38  	return Uint128{High, Low}
    39  }
    40  
    41  // Sub64 returns x-y.
    42  func (x Uint128) Sub64(y uint64) Uint128 {
    43  	Low, borrow := bits.Sub64(x.Low, y, 0)
    44  	High, _ := bits.Sub64(x.High, 0, borrow)
    45  	return Uint128{High, Low}
    46  }
    47  
    48  // Equals returns true if x == y.
    49  func (x Uint128) Equals(y Uint128) bool {
    50  	return x == y
    51  }
    52  
    53  // Equals64 returns true if x == y.
    54  func (x Uint128) Equals64(y uint64) bool {
    55  	return x.Low == y && x.High == 0
    56  }
    57  
    58  // And returns x&y.
    59  func (x Uint128) And(v Uint128) Uint128 {
    60  	return Uint128{x.High & v.High, x.Low & v.Low}
    61  }
    62  
    63  // And64 returns x&y.
    64  func (x Uint128) And64(y uint64) Uint128 {
    65  	return Uint128{Low: x.Low & y}
    66  }
    67  
    68  // Lsh returns x<<y.
    69  func (x Uint128) Lsh(y uint64) Uint128 {
    70  	z := Uint128{}
    71  	if y > 64 {
    72  		z.Low = 0
    73  		z.High = x.Low << (y - 64)
    74  	} else {
    75  		z.Low = x.Low << y
    76  		z.High = x.High<<y | x.Low>>(64-y)
    77  	}
    78  
    79  	return z
    80  }
    81  
    82  // Not returns ^x.
    83  func (x Uint128) Not() Uint128 {
    84  	return Uint128{^x.High, ^x.Low}
    85  }
    86  
    87  // Or returns x|y.
    88  func (x Uint128) Or(v Uint128) Uint128 {
    89  	return Uint128{x.High | v.High, x.Low | v.Low}
    90  }
    91  
    92  // Xor returns x^y.
    93  func (x Uint128) Xor(v Uint128) Uint128 {
    94  	return Uint128{x.High ^ v.High, x.Low ^ v.Low}
    95  }
    96  
    97  // CountOnes return num of 1 bits in x.
    98  func (x Uint128) CountOnes() int {
    99  	return bits.OnesCount64(x.Low) + bits.OnesCount64(x.High)
   100  }
   101  
   102  // TrailingZeros returns the number of trailing zero bits in x; the result is 128 for x == 0.
   103  func (x Uint128) TrailingZeros() int {
   104  	if x.Low > 0 {
   105  		return bits.TrailingZeros64(x.Low)
   106  	}
   107  	return 64 + bits.TrailingZeros64(x.High)
   108  }