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 }