diff --git a/tm2/pkg/overflow/README.md b/tm2/pkg/overflow/README.md index 55a9ba4c327..26ba7dc9985 100644 --- a/tm2/pkg/overflow/README.md +++ b/tm2/pkg/overflow/README.md @@ -2,26 +2,25 @@ Check for int/int8/int16/int64/int32 integer overflow in Golang arithmetic. -Forked from https://github.com/JohnCGriffin/overflow +Originally 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: -``` + +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: + +```sh go generate ``` + ### Synopsis -``` +```go package main import "fmt" import "math" -import "github.com/JohnCGriffin/overflow" +import "github.com/gnolang/gno/tm2/pkg/overflow" func main() { @@ -29,38 +28,33 @@ func main() { for i := 0; i < 10; i++ { sum, ok := overflow.Add(addend, i) - fmt.Printf("%v+%v -> (%v,%v)\n", + 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) + +```console +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. - - - - - - - +There's a good case to be made that a panic is an unidiomatic but proper +response. If 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. diff --git a/tm2/pkg/overflow/overflow_impl.go b/tm2/pkg/overflow/overflow_impl.go index a9a90c43835..0f057f65387 100644 --- a/tm2/pkg/overflow/overflow_impl.go +++ b/tm2/pkg/overflow/overflow_impl.go @@ -1,10 +1,8 @@ package overflow -// This is generated code, created by overflow_template.sh executed -// by "go generate" +// Code generated by overflow_template.sh from 'go generate'. DO NOT EDIT. -// Add8 performs + operation on two int8 operands -// returning a result and status +// Add8 performs + operation on two int8 operands, returning a result and status. func Add8(a, b int8) (int8, bool) { c := a + b if (c > a) == (b > 0) { @@ -13,7 +11,7 @@ func Add8(a, b int8) (int8, bool) { return c, false } -// Add8p is the unchecked panicing version of Add8 +// Add8p is the unchecked panicing version of Add8. func Add8p(a, b int8) int8 { r, ok := Add8(a, b) if !ok { @@ -22,8 +20,7 @@ func Add8p(a, b int8) int8 { return r } -// Sub8 performs - operation on two int8 operands -// returning a result and status +// Sub8 performs - operation on two int8 operands, returning a result and status. func Sub8(a, b int8) (int8, bool) { c := a - b if (c < a) == (b > 0) { @@ -32,7 +29,7 @@ func Sub8(a, b int8) (int8, bool) { return c, false } -// Sub8p is the unchecked panicing version of Sub8 +// Sub8p is the unchecked panicing version of Sub8. func Sub8p(a, b int8) int8 { r, ok := Sub8(a, b) if !ok { @@ -41,8 +38,7 @@ func Sub8p(a, b int8) int8 { return r } -// Mul8 performs * operation on two int8 operands -// returning a result and status +// Mul8 performs * operation on two int8 operands returning a result and status. func Mul8(a, b int8) (int8, bool) { if a == 0 || b == 0 { return 0, true @@ -56,7 +52,7 @@ func Mul8(a, b int8) (int8, bool) { return c, false } -// Mul8p is the unchecked panicing version of Mul8 +// Mul8p is the unchecked panicing version of Mul8. func Mul8p(a, b int8) int8 { r, ok := Mul8(a, b) if !ok { @@ -65,14 +61,13 @@ func Mul8p(a, b int8) int8 { return r } -// Div8 performs / operation on two int8 operands -// returning a result and status +// Div8 performs / operation on two int8 operands, returning a result and status. func Div8(a, b int8) (int8, bool) { q, _, ok := Quotient8(a, b) return q, ok } -// Div8p is the unchecked panicing version of Div8 +// Div8p is the unchecked panicing version of Div8. func Div8p(a, b int8) int8 { r, ok := Div8(a, b) if !ok { @@ -81,19 +76,19 @@ func Div8p(a, b int8) int8 { return r } -// Quotient8 performs + operation on two int8 operands -// returning a quotient, a remainder and status +// Quotient8 performs / operation on two int8 operands, returning a quotient, +// a remainder and status. func Quotient8(a, b int8) (int8, int8, bool) { if b == 0 { return 0, 0, false } c := a / b - status := (c < 0) == ((a < 0) != (b < 0)) - return c, a % b, status + status := (c < 0) == ((a < 0) != (b < 0)) || (c == 0) // no sign check for 0 quotient + return c, a%b, status } -// Add16 performs + operation on two int16 operands -// returning a result and status + +// Add16 performs + operation on two int16 operands, returning a result and status. func Add16(a, b int16) (int16, bool) { c := a + b if (c > a) == (b > 0) { @@ -102,7 +97,7 @@ func Add16(a, b int16) (int16, bool) { return c, false } -// Add16p is the unchecked panicing version of Add16 +// Add16p is the unchecked panicing version of Add16. func Add16p(a, b int16) int16 { r, ok := Add16(a, b) if !ok { @@ -111,8 +106,7 @@ func Add16p(a, b int16) int16 { return r } -// Sub16 performs - operation on two int16 operands -// returning a result and status +// Sub16 performs - operation on two int16 operands, returning a result and status. func Sub16(a, b int16) (int16, bool) { c := a - b if (c < a) == (b > 0) { @@ -121,7 +115,7 @@ func Sub16(a, b int16) (int16, bool) { return c, false } -// Sub16p is the unchecked panicing version of Sub16 +// Sub16p is the unchecked panicing version of Sub16. func Sub16p(a, b int16) int16 { r, ok := Sub16(a, b) if !ok { @@ -130,8 +124,7 @@ func Sub16p(a, b int16) int16 { return r } -// Mul16 performs * operation on two int16 operands -// returning a result and status +// Mul16 performs * operation on two int16 operands returning a result and status. func Mul16(a, b int16) (int16, bool) { if a == 0 || b == 0 { return 0, true @@ -145,7 +138,7 @@ func Mul16(a, b int16) (int16, bool) { return c, false } -// Mul16p is the unchecked panicing version of Mul16 +// Mul16p is the unchecked panicing version of Mul16. func Mul16p(a, b int16) int16 { r, ok := Mul16(a, b) if !ok { @@ -154,14 +147,13 @@ func Mul16p(a, b int16) int16 { return r } -// Div16 performs / operation on two int16 operands -// returning a result and status +// Div16 performs / operation on two int16 operands, returning a result and status. func Div16(a, b int16) (int16, bool) { q, _, ok := Quotient16(a, b) return q, ok } -// Div16p is the unchecked panicing version of Div16 +// Div16p is the unchecked panicing version of Div16. func Div16p(a, b int16) int16 { r, ok := Div16(a, b) if !ok { @@ -170,19 +162,19 @@ func Div16p(a, b int16) int16 { return r } -// Quotient16 performs + operation on two int16 operands -// returning a quotient, a remainder and status +// Quotient16 performs / operation on two int16 operands, returning a quotient, +// a remainder and status. func Quotient16(a, b int16) (int16, int16, bool) { if b == 0 { return 0, 0, false } c := a / b - status := (c < 0) == ((a < 0) != (b < 0)) - return c, a % b, status + status := (c < 0) == ((a < 0) != (b < 0)) || (c == 0) // no sign check for 0 quotient + return c, a%b, status } -// Add32 performs + operation on two int32 operands -// returning a result and status + +// Add32 performs + operation on two int32 operands, returning a result and status. func Add32(a, b int32) (int32, bool) { c := a + b if (c > a) == (b > 0) { @@ -191,7 +183,7 @@ func Add32(a, b int32) (int32, bool) { return c, false } -// Add32p is the unchecked panicing version of Add32 +// Add32p is the unchecked panicing version of Add32. func Add32p(a, b int32) int32 { r, ok := Add32(a, b) if !ok { @@ -200,8 +192,7 @@ func Add32p(a, b int32) int32 { return r } -// Sub32 performs - operation on two int32 operands -// returning a result and status +// Sub32 performs - operation on two int32 operands, returning a result and status. func Sub32(a, b int32) (int32, bool) { c := a - b if (c < a) == (b > 0) { @@ -210,7 +201,7 @@ func Sub32(a, b int32) (int32, bool) { return c, false } -// Sub32p is the unchecked panicing version of Sub32 +// Sub32p is the unchecked panicing version of Sub32. func Sub32p(a, b int32) int32 { r, ok := Sub32(a, b) if !ok { @@ -219,8 +210,7 @@ func Sub32p(a, b int32) int32 { return r } -// Mul32 performs * operation on two int32 operands -// returning a result and status +// Mul32 performs * operation on two int32 operands returning a result and status. func Mul32(a, b int32) (int32, bool) { if a == 0 || b == 0 { return 0, true @@ -234,7 +224,7 @@ func Mul32(a, b int32) (int32, bool) { return c, false } -// Mul32p is the unchecked panicing version of Mul32 +// Mul32p is the unchecked panicing version of Mul32. func Mul32p(a, b int32) int32 { r, ok := Mul32(a, b) if !ok { @@ -243,14 +233,13 @@ func Mul32p(a, b int32) int32 { return r } -// Div32 performs / operation on two int32 operands -// returning a result and status +// Div32 performs / operation on two int32 operands, returning a result and status. func Div32(a, b int32) (int32, bool) { q, _, ok := Quotient32(a, b) return q, ok } -// Div32p is the unchecked panicing version of Div32 +// Div32p is the unchecked panicing version of Div32. func Div32p(a, b int32) int32 { r, ok := Div32(a, b) if !ok { @@ -259,19 +248,19 @@ func Div32p(a, b int32) int32 { return r } -// Quotient32 performs + operation on two int32 operands -// returning a quotient, a remainder and status +// Quotient32 performs / operation on two int32 operands, returning a quotient, +// a remainder and status. func Quotient32(a, b int32) (int32, int32, bool) { if b == 0 { return 0, 0, false } c := a / b - status := (c < 0) == ((a < 0) != (b < 0)) - return c, a % b, status + status := (c < 0) == ((a < 0) != (b < 0)) || (c == 0) // no sign check for 0 quotient + return c, a%b, status } -// Add64 performs + operation on two int64 operands -// returning a result and status + +// Add64 performs + operation on two int64 operands, returning a result and status. func Add64(a, b int64) (int64, bool) { c := a + b if (c > a) == (b > 0) { @@ -280,7 +269,7 @@ func Add64(a, b int64) (int64, bool) { return c, false } -// Add64p is the unchecked panicing version of Add64 +// Add64p is the unchecked panicing version of Add64. func Add64p(a, b int64) int64 { r, ok := Add64(a, b) if !ok { @@ -289,8 +278,7 @@ func Add64p(a, b int64) int64 { return r } -// Sub64 performs - operation on two int64 operands -// returning a result and status +// Sub64 performs - operation on two int64 operands, returning a result and status. func Sub64(a, b int64) (int64, bool) { c := a - b if (c < a) == (b > 0) { @@ -299,7 +287,7 @@ func Sub64(a, b int64) (int64, bool) { return c, false } -// Sub64p is the unchecked panicing version of Sub64 +// Sub64p is the unchecked panicing version of Sub64. func Sub64p(a, b int64) int64 { r, ok := Sub64(a, b) if !ok { @@ -308,8 +296,7 @@ func Sub64p(a, b int64) int64 { return r } -// Mul64 performs * operation on two int64 operands -// returning a result and status +// Mul64 performs * operation on two int64 operands returning a result and status. func Mul64(a, b int64) (int64, bool) { if a == 0 || b == 0 { return 0, true @@ -323,7 +310,7 @@ func Mul64(a, b int64) (int64, bool) { return c, false } -// Mul64p is the unchecked panicing version of Mul64 +// Mul64p is the unchecked panicing version of Mul64. func Mul64p(a, b int64) int64 { r, ok := Mul64(a, b) if !ok { @@ -332,14 +319,13 @@ func Mul64p(a, b int64) int64 { return r } -// Div64 performs / operation on two int64 operands -// returning a result and status +// Div64 performs / operation on two int64 operands, returning a result and status. func Div64(a, b int64) (int64, bool) { q, _, ok := Quotient64(a, b) return q, ok } -// Div64p is the unchecked panicing version of Div64 +// Div64p is the unchecked panicing version of Div64. func Div64p(a, b int64) int64 { r, ok := Div64(a, b) if !ok { @@ -348,13 +334,14 @@ func Div64p(a, b int64) int64 { return r } -// Quotient64 performs + operation on two int64 operands -// returning a quotient, a remainder and status +// Quotient64 performs / operation on two int64 operands, returning a quotient, +// a remainder and status. func Quotient64(a, b int64) (int64, int64, bool) { if b == 0 { return 0, 0, false } c := a / b - status := (c < 0) == ((a < 0) != (b < 0)) - return c, a % b, status + status := (c < 0) == ((a < 0) != (b < 0)) || (c == 0) // no sign check for 0 quotient + return c, a%b, status } + diff --git a/tm2/pkg/overflow/overflow_template.sh b/tm2/pkg/overflow/overflow_template.sh index a2a85f2c581..0cc3c9595bf 100755 --- a/tm2/pkg/overflow/overflow_template.sh +++ b/tm2/pkg/overflow/overflow_template.sh @@ -4,109 +4,94 @@ exec > overflow_impl.go echo "package overflow -// This is generated code, created by overflow_template.sh executed -// by \"go generate\" - -" - +// Code generated by overflow_template.sh from 'go generate'. DO NOT EDIT." for SIZE in 8 16 32 64 do -echo " - -// Add${SIZE} performs + operation on two int${SIZE} operands -// returning a result and status + echo " +// Add${SIZE} performs + operation on two int${SIZE} operands, returning a result and status. func Add${SIZE}(a, b int${SIZE}) (int${SIZE}, bool) { - c := a + b - if (c > a) == (b > 0) { - return c, true - } - return c, false + c := a + b + if (c > a) == (b > 0) { + return c, true + } + return c, false } -// Add${SIZE}p is the unchecked panicing version of Add${SIZE} +// Add${SIZE}p is the unchecked panicing version of Add${SIZE}. func Add${SIZE}p(a, b int${SIZE}) int${SIZE} { - r, ok := Add${SIZE}(a, b) - if !ok { - panic(\"addition overflow\") - } - return r + r, ok := Add${SIZE}(a, b) + if !ok { + panic(\"addition overflow\") + } + return r } - -// Sub${SIZE} performs - operation on two int${SIZE} operands -// returning a result and status +// Sub${SIZE} performs - operation on two int${SIZE} operands, returning a result and status. func Sub${SIZE}(a, b int${SIZE}) (int${SIZE}, bool) { - c := a - b - if (c < a) == (b > 0) { - return c, true - } - return c, false + c := a - b + if (c < a) == (b > 0) { + return c, true + } + return c, false } -// Sub${SIZE}p is the unchecked panicing version of Sub${SIZE} +// Sub${SIZE}p is the unchecked panicing version of Sub${SIZE}. func Sub${SIZE}p(a, b int${SIZE}) int${SIZE} { - r, ok := Sub${SIZE}(a, b) - if !ok { - panic(\"subtraction overflow\") - } - return r + r, ok := Sub${SIZE}(a, b) + if !ok { + panic(\"subtraction overflow\") + } + return r } - -// Mul${SIZE} performs * operation on two int${SIZE} operands -// returning a result and status +// Mul${SIZE} performs * operation on two int${SIZE} operands returning a result and status. func Mul${SIZE}(a, b int${SIZE}) (int${SIZE}, bool) { - if a == 0 || b == 0 { - return 0, true - } - c := a * b - if (c < 0) == ((a < 0) != (b < 0)) { - if c/b == a { - return c, true - } - } - return c, false + if a == 0 || b == 0 { + return 0, true + } + c := a * b + if (c < 0) == ((a < 0) != (b < 0)) { + if c/b == a { + return c, true + } + } + return c, false } -// Mul${SIZE}p is the unchecked panicing version of Mul${SIZE} +// Mul${SIZE}p is the unchecked panicing version of Mul${SIZE}. func Mul${SIZE}p(a, b int${SIZE}) int${SIZE} { - r, ok := Mul${SIZE}(a, b) - if !ok { - panic(\"multiplication overflow\") - } - return r + r, ok := Mul${SIZE}(a, b) + if !ok { + panic(\"multiplication overflow\") + } + return r } - - -// Div${SIZE} performs / operation on two int${SIZE} operands -// returning a result and status +// Div${SIZE} performs / operation on two int${SIZE} operands, returning a result and status. func Div${SIZE}(a, b int${SIZE}) (int${SIZE}, bool) { - q, _, ok := Quotient${SIZE}(a, b) - return q, ok + q, _, ok := Quotient${SIZE}(a, b) + return q, ok } -// Div${SIZE}p is the unchecked panicing version of Div${SIZE} +// Div${SIZE}p is the unchecked panicing version of Div${SIZE}. func Div${SIZE}p(a, b int${SIZE}) int${SIZE} { - r, ok := Div${SIZE}(a, b) - if !ok { - panic(\"division failure\") - } - return r + r, ok := Div${SIZE}(a, b) + if !ok { + panic(\"division failure\") + } + return r } -// Quotient${SIZE} performs + operation on two int${SIZE} operands -// returning a quotient, a remainder and status +// Quotient${SIZE} performs / operation on two int${SIZE} operands, returning a quotient, +// a remainder and status. func Quotient${SIZE}(a, b int${SIZE}) (int${SIZE}, int${SIZE}, bool) { - if b == 0 { - return 0, 0, false - } - c := a / b - status := (c < 0) == ((a < 0) != (b < 0)) - return c, a % b, status + if b == 0 { + return 0, 0, false + } + c := a / b + status := (c < 0) == ((a < 0) != (b < 0)) || (c == 0) // no sign check for 0 quotient + return c, a%b, status } " done - -go run -modfile ../../../misc/devdeps/go.mod mvdan.cc/gofumpt -w overflow_impl.go diff --git a/tm2/pkg/overflow/overflow_test.go b/tm2/pkg/overflow/overflow_test.go index 2b2d345b55d..e6327c9e862 100644 --- a/tm2/pkg/overflow/overflow_test.go +++ b/tm2/pkg/overflow/overflow_test.go @@ -28,8 +28,7 @@ func TestAlgorithms(t *testing.T) { // now the verification result, ok := Add8(a8, b8) if ok && int64(result) != r64 { - t.Errorf("failed to fail on %v + %v = %v instead of %v\n", - a8, b8, result, r64) + t.Errorf("failed to fail on %v + %v = %v instead of %v\n", a8, b8, result, r64) errors++ } if !ok && int64(result) == r64 { @@ -45,8 +44,7 @@ func TestAlgorithms(t *testing.T) { // now the verification result, ok := Sub8(a8, b8) if ok && int64(result) != r64 { - t.Errorf("failed to fail on %v - %v = %v instead of %v\n", - a8, b8, result, r64) + t.Errorf("failed to fail on %v - %v = %v instead of %v\n", a8, b8, result, r64) } if !ok && int64(result) == r64 { t.Fail() @@ -61,8 +59,7 @@ func TestAlgorithms(t *testing.T) { // now the verification result, ok := Mul8(a8, b8) if ok && int64(result) != r64 { - t.Errorf("failed to fail on %v * %v = %v instead of %v\n", - a8, b8, result, r64) + t.Errorf("failed to fail on %v * %v = %v instead of %v\n", a8, b8, result, r64) errors++ } if !ok && int64(result) == r64 { @@ -78,11 +75,10 @@ func TestAlgorithms(t *testing.T) { // now the verification result, _, ok := Quotient8(a8, b8) if ok && int64(result) != r64 { - t.Errorf("failed to fail on %v / %v = %v instead of %v\n", - a8, b8, result, r64) + t.Errorf("failed to fail on %v / %v = %v instead of %v\n", a8, b8, result, r64) errors++ } - if !ok && result != 0 && int64(result) == r64 { + if !ok && int64(result) == r64 { t.Fail() errors++ }