mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-24 22:32:15 +00:00
first stab on checked ints
This commit is contained in:
parent
bbf15b3d09
commit
79210e658d
33
types/checked_ints.go
Normal file
33
types/checked_ints.go
Normal 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
|
||||||
|
|
||||||
|
}
|
61
types/checked_ints_test.go
Normal file
61
types/checked_ints_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user