|
|
@ -18,6 +18,7 @@ package math |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
|
|
|
|
"math/bits" |
|
|
|
"strconv" |
|
|
|
"strconv" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
@ -78,22 +79,20 @@ func MustParseUint64(s string) uint64 { |
|
|
|
return v |
|
|
|
return v |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// NOTE: The following methods need to be optimised using either bit checking or asm
|
|
|
|
// SafeSub returns x-y and checks for overflow.
|
|
|
|
|
|
|
|
|
|
|
|
// SafeSub returns subtraction result and whether overflow occurred.
|
|
|
|
|
|
|
|
func SafeSub(x, y uint64) (uint64, bool) { |
|
|
|
func SafeSub(x, y uint64) (uint64, bool) { |
|
|
|
return x - y, x < y |
|
|
|
diff, borrowOut := bits.Sub64(x, y, 0) |
|
|
|
|
|
|
|
return diff, borrowOut != 0 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// SafeAdd returns the result and whether overflow occurred.
|
|
|
|
// SafeAdd returns x+y and checks for overflow.
|
|
|
|
func SafeAdd(x, y uint64) (uint64, bool) { |
|
|
|
func SafeAdd(x, y uint64) (uint64, bool) { |
|
|
|
return x + y, y > MaxUint64-x |
|
|
|
sum, carryOut := bits.Add64(x, y, 0) |
|
|
|
|
|
|
|
return sum, carryOut != 0 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// SafeMul returns multiplication result and whether overflow occurred.
|
|
|
|
// SafeMul returns x*y and checks for overflow.
|
|
|
|
func SafeMul(x, y uint64) (uint64, bool) { |
|
|
|
func SafeMul(x, y uint64) (uint64, bool) { |
|
|
|
if x == 0 || y == 0 { |
|
|
|
hi, lo := bits.Mul64(x, y) |
|
|
|
return 0, false |
|
|
|
return lo, hi != 0 |
|
|
|
} |
|
|
|
|
|
|
|
return x * y, y > MaxUint64/x |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|