first stab on checked ints

This commit is contained in:
Ismail Khoffi 2018-10-26 18:06:34 +02:00
parent bbf15b3d09
commit 79210e658d
2 changed files with 94 additions and 0 deletions

33
types/checked_ints.go Normal file
View File

@ -0,0 +1,33 @@
package types
import (
"errors"
"math"
)
var ErrOverflowInt = errors.New("integer overflow")
type CheckedInt32 int32
type CheckedUint32 uint32
type CheckedInt64 int64
type CheckedUint64 int64
func (i32 CheckedInt32) CheckedAdd(otherI32 CheckedInt32) (CheckedInt32, error) {
if otherI32 > 0 && (i32 > math.MaxInt32-otherI32) {
return 0, ErrOverflowInt
} else if otherI32 < 0 && (i32 < math.MinInt32-otherI32) {
return 0, ErrOverflowInt
}
return i32 + otherI32, nil
}
func (i32 CheckedInt32) CheckedSub(otherI32 CheckedInt32) (CheckedInt32, error) {
if otherI32 > 0 && (i32 < math.MinInt32+otherI32) {
return 0, ErrOverflowInt
} else if otherI32 < 0 && (i32 > math.MaxInt32+otherI32) {
return 0, ErrOverflowInt
}
return i32 - otherI32, nil
}

View File

@ -0,0 +1,61 @@
package types
import (
"math"
"testing"
"github.com/stretchr/testify/assert"
)
func TestCheckedInt32_CheckedAdd(t *testing.T) {
tcs := []struct {
val1 int32
val2 int32
sum int32
wantErr bool
}{
0: {math.MaxInt32, 1, 0, true},
1: {math.MinInt32, 1, math.MinInt32 + 1, false},
2: {math.MaxInt32, math.MaxInt32, 0, true},
3: {0, math.MaxInt32, math.MaxInt32, false},
4: {0, 1, 1, false},
5: {1, 1, 2, false},
}
for i, tc := range tcs {
v1 := CheckedInt32(tc.val1)
v2 := CheckedInt32(tc.val2)
sum, err := v1.CheckedAdd(v2)
if tc.wantErr {
assert.Error(t, err, "Should fail: %v", i)
assert.Zero(t, sum, "Got invalid sum for case %v", i)
} else {
assert.EqualValues(t, tc.sum, sum)
}
}
}
func TestCheckedInt32_CheckedSub(t *testing.T) {
tcs := []struct {
val1 int32
val2 int32
sum int32
wantErr bool
}{
0: {math.MaxInt32, math.MaxInt32, 0, false},
1: {math.MinInt32, 1, 0, true},
2: {math.MinInt32 + 1, 1, math.MinInt32, false},
3: {1, 1, 0, false},
4: {1, 2, -1, false},
}
for i, tc := range tcs {
v1 := CheckedInt32(tc.val1)
v2 := CheckedInt32(tc.val2)
sum, err := v1.CheckedSub(v2)
if tc.wantErr {
assert.Error(t, err, "Should fail: %v", i)
assert.Zero(t, sum, "Got invalid sum for case %v", i)
} else {
assert.EqualValues(t, tc.sum, sum, "failed: %v", i)
}
}
}