Skip to content

Commit d598466

Browse files
committed
Add support for uint type overflow detection
1 parent 46fa312 commit d598466

File tree

5 files changed

+612
-7
lines changed

5 files changed

+612
-7
lines changed

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[![Build Status](https://travis-ci.org/JohnCGriffin/overflow.png)](https://travis-ci.org/JohnCGriffin/overflow)
22
# overflow
3-
Check for int/int8/int16/int64/int32 integer overflow in Golang arithmetic.
3+
Check for integer overflow in Golang arithmetic.
44
### Install
55
```
66
go get github.com/johncgriffin/overflow
@@ -46,8 +46,7 @@ yields the output
4646
9223372036854775802+9 -> (0,false)
4747
```
4848

49-
For int, int64, and int32 types, provide Add, Add32, Add64, Sub, Sub32, Sub64, etc.
50-
Unsigned types not covered at the moment, but such additions are welcome.
49+
For (u)int types, provide (U)Add, (U)Sub, (U)Mul, (U)Div, (U)Quotient, etc.
5150

5251
### Stay calm and panic
5352

overflow.go

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
/*Package overflow offers overflow-checked integer arithmetic operations
1+
/*
2+
Package overflow offers overflow-checked integer arithmetic operations
23
for int, int32, and int64. Each of the operations returns a
34
result,bool combination. This was prompted by the need to know when
45
to flow into higher precision types from the math.big library.
@@ -16,7 +17,8 @@ overflow.Add(math.MaxInt64,1) -> (0, false)
1617
Add, Sub, Mul, Div are for int. Add64, Add32, etc. are specifically sized.
1718
1819
If anybody wishes an unsigned version, submit a pull request for code
19-
and new tests. */
20+
and new tests.
21+
*/
2022
package overflow
2123

2224
//go:generate ./overflow_template.sh
@@ -50,6 +52,16 @@ func Add(a, b int) (int, bool) {
5052
return int(r32), ok
5153
}
5254

55+
// UAdd sums two uints, returning the result and a boolean status.
56+
func UAdd(a, b uint) (uint, bool) {
57+
if _is64Bit() {
58+
r64, ok := UAdd64(uint64(a), uint64(b))
59+
return uint(r64), ok
60+
}
61+
r32, ok := UAdd32(uint32(a), uint32(b))
62+
return uint(r32), ok
63+
}
64+
5365
// Sub returns the difference of two ints and a boolean status.
5466
func Sub(a, b int) (int, bool) {
5567
if _is64Bit() {
@@ -60,6 +72,16 @@ func Sub(a, b int) (int, bool) {
6072
return int(r32), ok
6173
}
6274

75+
// USub returns the difference of two uints and a boolean status.
76+
func USub(a, b uint) (uint, bool) {
77+
if _is64Bit() {
78+
r64, ok := USub64(uint64(a), uint64(b))
79+
return uint(r64), ok
80+
}
81+
r32, ok := USub32(uint32(a), uint32(b))
82+
return uint(r32), ok
83+
}
84+
6385
// Mul returns the product of two ints and a boolean status.
6486
func Mul(a, b int) (int, bool) {
6587
if _is64Bit() {
@@ -70,6 +92,16 @@ func Mul(a, b int) (int, bool) {
7092
return int(r32), ok
7193
}
7294

95+
// UMul returns the product of two uints and a boolean status.
96+
func UMul(a, b uint) (uint, bool) {
97+
if _is64Bit() {
98+
r64, ok := UMul64(uint64(a), uint64(b))
99+
return uint(r64), ok
100+
}
101+
r32, ok := UMul32(uint32(a), uint32(b))
102+
return uint(r32), ok
103+
}
104+
73105
// Div returns the quotient of two ints and a boolean status
74106
func Div(a, b int) (int, bool) {
75107
if _is64Bit() {
@@ -80,6 +112,16 @@ func Div(a, b int) (int, bool) {
80112
return int(r32), ok
81113
}
82114

115+
// UDiv returns the quotient of two uints and a boolean status
116+
func UDiv(a, b uint) (uint, bool) {
117+
if _is64Bit() {
118+
r64, ok := UDiv64(uint64(a), uint64(b))
119+
return uint(r64), ok
120+
}
121+
r32, ok := UDiv32(uint32(a), uint32(b))
122+
return uint(r32), ok
123+
}
124+
83125
// Quotient returns the quotient, remainder and status of two ints
84126
func Quotient(a, b int) (int, int, bool) {
85127
if _is64Bit() {
@@ -90,6 +132,16 @@ func Quotient(a, b int) (int, int, bool) {
90132
return int(q32), int(r32), ok
91133
}
92134

135+
// UQuotient returns the quotient, remainder and status of two uints
136+
func UQuotient(a, b uint) (uint, uint, bool) {
137+
if _is64Bit() {
138+
uq64, ur64, ok := UQuotient64(uint64(a), uint64(b))
139+
return uint(uq64), uint(ur64), ok
140+
}
141+
uq32, ur32, ok := UQuotient32(uint32(a), uint32(b))
142+
return uint(uq32), uint(ur32), ok
143+
}
144+
93145
/************* Panic versions for int ****************/
94146

95147
// Addp returns the sum of two ints, panicking on overflow
@@ -101,6 +153,15 @@ func Addp(a, b int) int {
101153
return r
102154
}
103155

156+
// UAddp returns the sum of two uints, panicking on overflow
157+
func UAddp(a, b uint) uint {
158+
r, ok := UAdd(a, b)
159+
if !ok {
160+
panic("addition overflow")
161+
}
162+
return r
163+
}
164+
104165
// Subp returns the difference of two ints, panicking on overflow.
105166
func Subp(a, b int) int {
106167
r, ok := Sub(a, b)
@@ -110,6 +171,15 @@ func Subp(a, b int) int {
110171
return r
111172
}
112173

174+
// USubp returns the difference of two uints, panicking on overflow.
175+
func USubp(a, b uint) uint {
176+
r, ok := USub(a, b)
177+
if !ok {
178+
panic("subtraction overflow")
179+
}
180+
return r
181+
}
182+
113183
// Mulp returns the product of two ints, panicking on overflow.
114184
func Mulp(a, b int) int {
115185
r, ok := Mul(a, b)
@@ -119,6 +189,15 @@ func Mulp(a, b int) int {
119189
return r
120190
}
121191

192+
// UMulp returns the product of two uints, panicking on overflow.
193+
func UMulp(a, b uint) uint {
194+
r, ok := UMul(a, b)
195+
if !ok {
196+
panic("multiplication overflow")
197+
}
198+
return r
199+
}
200+
122201
// Divp returns the quotient of two ints, panicking on overflow.
123202
func Divp(a, b int) int {
124203
r, ok := Div(a, b)
@@ -127,3 +206,12 @@ func Divp(a, b int) int {
127206
}
128207
return r
129208
}
209+
210+
// UDivp returns the quotient of two uints, panicking on overflow.
211+
func UDivp(a, b uint) uint {
212+
r, ok := UDiv(a, b)
213+
if !ok {
214+
panic("division failure")
215+
}
216+
return r
217+
}

0 commit comments

Comments
 (0)