github.com/prysmaticlabs/prysm@v1.4.4/shared/mathutil/math_helper.go (about) 1 // Package mathutil includes important helpers for Ethereum such as fast integer square roots. 2 package mathutil 3 4 import ( 5 "errors" 6 "math" 7 "math/bits" 8 9 "github.com/thomaso-mirodin/intmath/u64" 10 ) 11 12 // Common square root values. 13 var squareRootTable = map[uint64]uint64{ 14 4: 2, 15 16: 4, 16 64: 8, 17 256: 16, 18 1024: 32, 19 4096: 64, 20 16384: 128, 21 65536: 256, 22 262144: 512, 23 1048576: 1024, 24 4194304: 2048, 25 } 26 27 // IntegerSquareRoot defines a function that returns the 28 // largest possible integer root of a number using go's standard library. 29 func IntegerSquareRoot(n uint64) uint64 { 30 if v, ok := squareRootTable[n]; ok { 31 return v 32 } 33 34 // Golang floating point precision may be lost above 52 bits, so we use a 35 // non floating point method. u64.Sqrt is about x2.5 slower than math.Sqrt. 36 if n >= 1<<52 { 37 return u64.Sqrt(n) 38 } 39 40 return uint64(math.Sqrt(float64(n))) 41 } 42 43 // CeilDiv8 divides the input number by 8 44 // and takes the ceiling of that number. 45 func CeilDiv8(n int) int { 46 ret := n / 8 47 if n%8 > 0 { 48 ret++ 49 } 50 51 return ret 52 } 53 54 // IsPowerOf2 returns true if n is an 55 // exact power of two. False otherwise. 56 func IsPowerOf2(n uint64) bool { 57 return n != 0 && (n&(n-1)) == 0 58 } 59 60 // PowerOf2 returns an integer that is the provided 61 // exponent of 2. Can only return powers of 2 till 63, 62 // after that it overflows 63 func PowerOf2(n uint64) uint64 { 64 if n >= 64 { 65 panic("integer overflow") 66 } 67 return 1 << n 68 } 69 70 // Max returns the larger integer of the two 71 // given ones.This is used over the Max function 72 // in the standard math library because that max function 73 // has to check for some special floating point cases 74 // making it slower by a magnitude of 10. 75 func Max(a, b uint64) uint64 { 76 if a > b { 77 return a 78 } 79 return b 80 } 81 82 // Min returns the smaller integer of the two 83 // given ones. This is used over the Min function 84 // in the standard math library because that min function 85 // has to check for some special floating point cases 86 // making it slower by a magnitude of 10. 87 func Min(a, b uint64) uint64 { 88 if a < b { 89 return a 90 } 91 return b 92 } 93 94 // Mul64 multiples 2 64-bit unsigned integers and checks if they 95 // lead to an overflow. If they do not, it returns the result 96 // without an error. 97 func Mul64(a, b uint64) (uint64, error) { 98 overflows, val := bits.Mul64(a, b) 99 if overflows > 0 { 100 return 0, errors.New("multiplication overflows") 101 } 102 return val, nil 103 } 104 105 // Add64 adds 2 64-bit unsigned integers and checks if they 106 // lead to an overflow. If they do not, it returns the result 107 // without an error. 108 func Add64(a, b uint64) (uint64, error) { 109 res, carry := bits.Add64(a, b, 0 /* carry */) 110 if carry > 0 { 111 return 0, errors.New("addition overflows") 112 } 113 return res, nil 114 }