-
Notifications
You must be signed in to change notification settings - Fork 383
Commit
We remove the dependency on gnolang/overflow, a clone of https://github.com/JohnCGriffin/overflow which is now unmaintained, and import it into gno/tm2/pkg/overflow. We can now have full control on it, fix it and improve it. This PR just changes the import path, no content change is done yet. --------- Co-authored-by: Morgan Bazalgette <[email protected]>
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# overflow | ||
|
||
Check for int/int8/int16/int64/int32 integer overflow in Golang arithmetic. | ||
|
||
Forked from https://github.com/JohnCGriffin/overflow | ||
|
||
### Install | ||
``` | ||
go get github.com/johncgriffin/overflow | ||
``` | ||
Note that because Go has no template types, the majority of repetitive code is | ||
generated by overflow_template.sh. If you have to change an | ||
algorithm, change it there and regenerate the Go code via: | ||
``` | ||
go generate | ||
``` | ||
### Synopsis | ||
|
||
``` | ||
package main | ||
import "fmt" | ||
import "math" | ||
import "github.com/JohnCGriffin/overflow" | ||
func main() { | ||
addend := math.MaxInt64 - 5 | ||
for i := 0; i < 10; i++ { | ||
sum, ok := overflow.Add(addend, i) | ||
fmt.Printf("%v+%v -> (%v,%v)\n", | ||
addend, i, sum, ok) | ||
} | ||
} | ||
``` | ||
yields the output | ||
``` | ||
9223372036854775802+0 -> (9223372036854775802,true) | ||
9223372036854775802+1 -> (9223372036854775803,true) | ||
9223372036854775802+2 -> (9223372036854775804,true) | ||
9223372036854775802+3 -> (9223372036854775805,true) | ||
9223372036854775802+4 -> (9223372036854775806,true) | ||
9223372036854775802+5 -> (9223372036854775807,true) | ||
9223372036854775802+6 -> (0,false) | ||
9223372036854775802+7 -> (0,false) | ||
9223372036854775802+8 -> (0,false) | ||
9223372036854775802+9 -> (0,false) | ||
``` | ||
|
||
For int, int64, and int32 types, provide Add, Add32, Add64, Sub, Sub32, Sub64, etc. | ||
Unsigned types not covered at the moment, but such additions are welcome. | ||
|
||
### Stay calm and panic | ||
|
||
There's a good case to be made that a panic is an unidiomatic but proper response. Iff you | ||
believe that there's no valid way to continue your program after math goes wayward, you can | ||
use the easier Addp, Mulp, Subp, and Divp versions which return the normal result or panic. | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/* | ||
Package overflow offers overflow-checked integer arithmetic operations | ||
for int, int32, and int64. Each of the operations returns a | ||
result,bool combination. This was prompted by the need to know when | ||
to flow into higher precision types from the math.big library. | ||
For instance, assuing a 64 bit machine: | ||
10 + 20 -> 30 | ||
int(math.MaxInt64) + 1 -> -9223372036854775808 | ||
whereas | ||
overflow.Add(10,20) -> (30, true) | ||
overflow.Add(math.MaxInt64,1) -> (0, false) | ||
Add, Sub, Mul, Div are for int. Add64, Add32, etc. are specifically sized. | ||
If anybody wishes an unsigned version, submit a pull request for code | ||
and new tests. | ||
*/ | ||
package overflow | ||
|
||
//go:generate ./overflow_template.sh | ||
|
||
import "math" | ||
|
||
func _is64Bit() bool { | ||
maxU32 := uint(math.MaxUint32) | ||
return ((maxU32 << 1) >> 1) == maxU32 | ||
} | ||
|
||
/********** PARTIAL TEST COVERAGE FROM HERE DOWN ************* | ||
The only way that I could see to do this is a combination of | ||
my normal 64 bit system and a GopherJS running on Node. My | ||
understanding is that its ints are 32 bit. | ||
So, FEEL FREE to carefully review the code visually. | ||
*************************************************************/ | ||
|
||
// Unspecified size, i.e. normal signed int | ||
|
||
// Add sums two ints, returning the result and a boolean status. | ||
func Add(a, b int) (int, bool) { | ||
if _is64Bit() { | ||
r64, ok := Add64(int64(a), int64(b)) | ||
return int(r64), ok | ||
} | ||
r32, ok := Add32(int32(a), int32(b)) | ||
return int(r32), ok | ||
} | ||
|
||
// Sub returns the difference of two ints and a boolean status. | ||
func Sub(a, b int) (int, bool) { | ||
if _is64Bit() { | ||
r64, ok := Sub64(int64(a), int64(b)) | ||
return int(r64), ok | ||
} | ||
r32, ok := Sub32(int32(a), int32(b)) | ||
return int(r32), ok | ||
} | ||
|
||
// Mul returns the product of two ints and a boolean status. | ||
func Mul(a, b int) (int, bool) { | ||
if _is64Bit() { | ||
r64, ok := Mul64(int64(a), int64(b)) | ||
return int(r64), ok | ||
} | ||
r32, ok := Mul32(int32(a), int32(b)) | ||
return int(r32), ok | ||
} | ||
|
||
// Div returns the quotient of two ints and a boolean status | ||
func Div(a, b int) (int, bool) { | ||
if _is64Bit() { | ||
r64, ok := Div64(int64(a), int64(b)) | ||
return int(r64), ok | ||
} | ||
r32, ok := Div32(int32(a), int32(b)) | ||
return int(r32), ok | ||
} | ||
|
||
// Quotient returns the quotient, remainder and status of two ints | ||
func Quotient(a, b int) (int, int, bool) { | ||
if _is64Bit() { | ||
q64, r64, ok := Quotient64(int64(a), int64(b)) | ||
return int(q64), int(r64), ok | ||
} | ||
q32, r32, ok := Quotient32(int32(a), int32(b)) | ||
return int(q32), int(r32), ok | ||
} | ||
|
||
/************* Panic versions for int ****************/ | ||
|
||
// Addp returns the sum of two ints, panicking on overflow | ||
func Addp(a, b int) int { | ||
r, ok := Add(a, b) | ||
if !ok { | ||
panic("addition overflow") | ||
} | ||
return r | ||
} | ||
|
||
// Subp returns the difference of two ints, panicking on overflow. | ||
func Subp(a, b int) int { | ||
r, ok := Sub(a, b) | ||
if !ok { | ||
panic("subtraction overflow") | ||
} | ||
return r | ||
} | ||
|
||
// Mulp returns the product of two ints, panicking on overflow. | ||
func Mulp(a, b int) int { | ||
r, ok := Mul(a, b) | ||
if !ok { | ||
panic("multiplication overflow") | ||
} | ||
return r | ||
} | ||
|
||
// Divp returns the quotient of two ints, panicking on overflow. | ||
func Divp(a, b int) int { | ||
r, ok := Div(a, b) | ||
if !ok { | ||
panic("division failure") | ||
} | ||
return r | ||
} |