From a4355be058c80df56860abe24ae2d649dbf4d208 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 9 Jul 2020 17:45:49 +0200 Subject: [PATCH] common/math: use math/bits intrinsics for Safe* (#21316) This is a resubmit of ledgerwatch/turbo-geth#556. The performance benefit of this change is negligible, but it does remove a TODO. --- common/math/integer.go | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/common/math/integer.go b/common/math/integer.go index 7eff4d3b0001d..17a9fb1375d13 100644 --- a/common/math/integer.go +++ b/common/math/integer.go @@ -18,6 +18,7 @@ package math import ( "fmt" + "math/bits" "strconv" ) @@ -78,22 +79,20 @@ func MustParseUint64(s string) uint64 { return v } -// NOTE: The following methods need to be optimised using either bit checking or asm - -// SafeSub returns subtraction result and whether overflow occurred. +// SafeSub returns x-y and checks for overflow. 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) { - 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) { - if x == 0 || y == 0 { - return 0, false - } - return x * y, y > MaxUint64/x + hi, lo := bits.Mul64(x, y) + return lo, hi != 0 }