diff --git a/utils/math/math.go b/utils/math/math.go index cdd1fc42..a5f10921 100644 --- a/utils/math/math.go +++ b/utils/math/math.go @@ -17,18 +17,31 @@ func Min(a, b int) int { return a } +// intSize is either 32 or 64. +const intSize = 32 << (^uint(0) >> 63) + // Abs 返回绝对值,该函数将被内联 func Abs(x int) int { - if x < 0 { - return -x - } - return x + // m := -1 if x < 0. m := 0 otherwise. + m := x >> (intSize - 1) + + // In two's complement representation, the negative number + // of any number (except the smallest one) can be computed + // by flipping all the bits and add 1. This is faster than + // code with a branch. + // See Hacker's Delight, section 2-4. + return (x ^ m) - m } // Abs64 返回绝对值,该函数将被内联 func Abs64(x int64) int64 { - if x < 0 { - return -x - } - return x + // m := -1 if x < 0. m := 0 otherwise. + m := x >> (64 - 1) + + // In two's complement representation, the negative number + // of any number (except the smallest one) can be computed + // by flipping all the bits and add 1. This is faster than + // code with a branch. + // See Hacker's Delight, section 2-4. + return (x ^ m) - m }