github.com/FUSIONFoundation/efsn@v3.6.2-0.20200916075423-dbb5dd5d2cc7+incompatible/common/overflow/overflow.go (about) 1 /*Package overflow offers overflow-checked integer arithmetic operations 2 for int, int32, and int64. Each of the operations returns a 3 result,bool combination. This was prompted by the need to know when 4 to flow into higher precision types from the math.big library. 5 6 For instance, assuing a 64 bit machine: 7 8 10 + 20 -> 30 9 int(math.MaxInt64) + 1 -> -9223372036854775808 10 11 whereas 12 13 overflow.Add(10,20) -> (30, true) 14 overflow.Add(math.MaxInt64,1) -> (0, false) 15 16 Add, Sub, Mul, Div are for int. Add64, Add32, etc. are specifically sized. 17 18 If anybody wishes an unsigned version, submit a pull request for code 19 and new tests. */ 20 package overflow 21 22 //go:generate ./overflow_template.sh 23 24 import "math" 25 26 func _is64Bit() bool { 27 maxU32 := uint(math.MaxUint32) 28 return ((maxU32 << 1) >> 1) == maxU32 29 } 30 31 /********** PARTIAL TEST COVERAGE FROM HERE DOWN ************* 32 33 The only way that I could see to do this is a combination of 34 my normal 64 bit system and a GopherJS running on Node. My 35 understanding is that its ints are 32 bit. 36 37 So, FEEL FREE to carefully review the code visually. 38 39 *************************************************************/ 40 41 // Unspecified size, i.e. normal signed int 42 43 // Add sums two ints, returning the result and a boolean status. 44 func Add(a, b int) (int, bool) { 45 if _is64Bit() { 46 r64, ok := Add64(int64(a), int64(b)) 47 return int(r64), ok 48 } 49 r32, ok := Add32(int32(a), int32(b)) 50 return int(r32), ok 51 } 52 53 // Sub returns the difference of two ints and a boolean status. 54 func Sub(a, b int) (int, bool) { 55 if _is64Bit() { 56 r64, ok := Sub64(int64(a), int64(b)) 57 return int(r64), ok 58 } 59 r32, ok := Sub32(int32(a), int32(b)) 60 return int(r32), ok 61 } 62 63 // Mul returns the product of two ints and a boolean status. 64 func Mul(a, b int) (int, bool) { 65 if _is64Bit() { 66 r64, ok := Mul64(int64(a), int64(b)) 67 return int(r64), ok 68 } 69 r32, ok := Mul32(int32(a), int32(b)) 70 return int(r32), ok 71 } 72 73 // Div returns the quotient of two ints and a boolean status 74 func Div(a, b int) (int, bool) { 75 if _is64Bit() { 76 r64, ok := Div64(int64(a), int64(b)) 77 return int(r64), ok 78 } 79 r32, ok := Div32(int32(a), int32(b)) 80 return int(r32), ok 81 } 82 83 // Quotient returns the quotient, remainder and status of two ints 84 func Quotient(a, b int) (int, int, bool) { 85 if _is64Bit() { 86 q64, r64, ok := Quotient64(int64(a), int64(b)) 87 return int(q64), int(r64), ok 88 } 89 q32, r32, ok := Quotient32(int32(a), int32(b)) 90 return int(q32), int(r32), ok 91 } 92 93 /************* Panic versions for int ****************/ 94 95 // Addp returns the sum of two ints, panicking on overflow 96 func Addp(a, b int) int { 97 r, ok := Add(a, b) 98 if !ok { 99 panic("addition overflow") 100 } 101 return r 102 } 103 104 // Subp returns the difference of two ints, panicking on overflow. 105 func Subp(a, b int) int { 106 r, ok := Sub(a, b) 107 if !ok { 108 panic("subtraction overflow") 109 } 110 return r 111 } 112 113 // Mulp returns the product of two ints, panicking on overflow. 114 func Mulp(a, b int) int { 115 r, ok := Mul(a, b) 116 if !ok { 117 panic("multiplication overflow") 118 } 119 return r 120 } 121 122 // Divp returns the quotient of two ints, panicking on overflow. 123 func Divp(a, b int) int { 124 r, ok := Div(a, b) 125 if !ok { 126 panic("division failure") 127 } 128 return r 129 }