Skip to content

Commit

Permalink
Limit min/max functions to Signed
Browse files Browse the repository at this point in the history
  • Loading branch information
PlasmaPower committed May 16, 2024
1 parent 4f72ebb commit bd880e9
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 37 deletions.
30 changes: 10 additions & 20 deletions util/arbmath/math.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,32 +259,22 @@ func BigFloatMulByUint(multiplicand *big.Float, multiplier uint64) *big.Float {
return new(big.Float).Mul(multiplicand, UintToBigFloat(multiplier))
}

func MaxIntValue[T Integer]() T {
allBits := ^T(0)
if allBits < 0 {
// This is a signed integer
return T((uint64(1) << (8*unsafe.Sizeof(allBits) - 1)) - 1)
}
return allBits
func MaxSignedValue[T Signed]() T {
return T((uint64(1) << (8*unsafe.Sizeof(T(0)) - 1)) - 1)
}

func MinIntValue[T Integer]() T {
allBits := ^T(0)
if allBits < 0 {
// This is a signed integer
return T(uint64(1) << ((8 * unsafe.Sizeof(allBits)) - 1))
}
return 0
func MinSignedValue[T Signed]() T {
return T(uint64(1) << ((8 * unsafe.Sizeof(T(0))) - 1))
}

// SaturatingAdd add two integers without overflow
func SaturatingAdd[T Signed](a, b T) T {
sum := a + b
if b > 0 && sum < a {
sum = MaxIntValue[T]()
sum = MaxSignedValue[T]()
}
if b < 0 && sum > a {
sum = MinIntValue[T]()
sum = MinSignedValue[T]()
}
return sum
}
Expand Down Expand Up @@ -329,9 +319,9 @@ func SaturatingMul[T Signed](a, b T) T {
product := a * b
if b != 0 && product/b != a {
if (a > 0 && b > 0) || (a < 0 && b < 0) {
product = MaxIntValue[T]()
product = MaxSignedValue[T]()
} else {
product = MinIntValue[T]()
product = MinSignedValue[T]()
}
}
return product
Expand Down Expand Up @@ -381,8 +371,8 @@ func SaturatingCastToUint(value *big.Int) uint64 {

// Negates an int without underflow
func SaturatingNeg[T Signed](value T) T {
if value < 0 && value == MinIntValue[T]() {
return MaxIntValue[T]()
if value < 0 && value == MinSignedValue[T]() {
return MaxSignedValue[T]()
}
return -value
}
Expand Down
10 changes: 5 additions & 5 deletions util/arbmath/math_fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ func toBig[T Signed](a T) *big.Int {
}

func saturatingBigToInt[T Signed](a *big.Int) T {
// MinIntValue and MaxIntValue are already separately tested
if a.Cmp(toBig(MaxIntValue[T]())) > 0 {
return MaxIntValue[T]()
// MinSignedValue and MaxSignedValue are already separately tested
if a.Cmp(toBig(MaxSignedValue[T]())) > 0 {
return MaxSignedValue[T]()
}
if a.Cmp(toBig(MinIntValue[T]())) < 0 {
return MinIntValue[T]()
if a.Cmp(toBig(MinSignedValue[T]())) < 0 {
return MinSignedValue[T]()
}
return T(a.Int64())
}
Expand Down
20 changes: 8 additions & 12 deletions util/arbmath/math_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,26 +121,22 @@ func TestSlices(t *testing.T) {
assert_eq(SliceWithRunoff(data, 7, 8), []uint8{})
}

func testMinMaxValues[T Integer](t *testing.T, min T, max T) {
gotMin := MinIntValue[T]()
func testMinMaxSignedValues[T Signed](t *testing.T, min T, max T) {
gotMin := MinSignedValue[T]()
if gotMin != min {
Fail(t, "expected min", min, "but got", gotMin)
}
gotMax := MaxIntValue[T]()
gotMax := MaxSignedValue[T]()
if gotMax != max {
Fail(t, "expected max", max, "but got", gotMax)
}
}

func TestMinMaxValues(t *testing.T) {
testMinMaxValues[uint8](t, 0, math.MaxUint8)
testMinMaxValues[uint16](t, 0, math.MaxUint16)
testMinMaxValues[uint32](t, 0, math.MaxUint32)
testMinMaxValues[uint64](t, 0, math.MaxUint64)
testMinMaxValues[int8](t, math.MinInt8, math.MaxInt8)
testMinMaxValues[int16](t, math.MinInt16, math.MaxInt16)
testMinMaxValues[int32](t, math.MinInt32, math.MaxInt32)
testMinMaxValues[int64](t, math.MinInt64, math.MaxInt64)
func TestMinMaxSignedValues(t *testing.T) {
testMinMaxSignedValues[int8](t, math.MinInt8, math.MaxInt8)
testMinMaxSignedValues[int16](t, math.MinInt16, math.MaxInt16)
testMinMaxSignedValues[int32](t, math.MinInt32, math.MaxInt32)
testMinMaxSignedValues[int64](t, math.MinInt64, math.MaxInt64)
}

func TestSaturatingAdd(t *testing.T) {
Expand Down

0 comments on commit bd880e9

Please sign in to comment.