diff options
Diffstat (limited to 'src/math/bits/bits.go')
-rw-r--r-- | src/math/bits/bits.go | 49 |
1 files changed, 19 insertions, 30 deletions
diff --git a/src/math/bits/bits.go b/src/math/bits/bits.go index 24d910c27e..1a85485a5a 100644 --- a/src/math/bits/bits.go +++ b/src/math/bits/bits.go @@ -332,23 +332,21 @@ func Len64(x uint64) (n int) { // The carry input must be 0 or 1; otherwise the behavior is undefined. // The carryOut output is guaranteed to be 0 or 1. func Add(x, y, carry uint) (sum, carryOut uint) { - yc := y + carry - sum = x + yc - if sum < x || yc < y { - carryOut = 1 + if UintSize == 32 { + s32, c32 := Add32(uint32(x), uint32(y), uint32(carry)) + return uint(s32), uint(c32) } - return + s64, c64 := Add64(uint64(x), uint64(y), uint64(carry)) + return uint(s64), uint(c64) } // Add32 returns the sum with carry of x, y and carry: sum = x + y + carry. // The carry input must be 0 or 1; otherwise the behavior is undefined. // The carryOut output is guaranteed to be 0 or 1. func Add32(x, y, carry uint32) (sum, carryOut uint32) { - yc := y + carry - sum = x + yc - if sum < x || yc < y { - carryOut = 1 - } + sum64 := uint64(x) + uint64(y) + uint64(carry) + sum = uint32(sum64) + carryOut = uint32(sum64 >> 32) return } @@ -356,11 +354,8 @@ func Add32(x, y, carry uint32) (sum, carryOut uint32) { // The carry input must be 0 or 1; otherwise the behavior is undefined. // The carryOut output is guaranteed to be 0 or 1. func Add64(x, y, carry uint64) (sum, carryOut uint64) { - yc := y + carry - sum = x + yc - if sum < x || yc < y { - carryOut = 1 - } + sum = x + y + carry + carryOut = ((x & y) | ((x | y) &^ sum)) >> 63 return } @@ -370,23 +365,20 @@ func Add64(x, y, carry uint64) (sum, carryOut uint64) { // The borrow input must be 0 or 1; otherwise the behavior is undefined. // The borrowOut output is guaranteed to be 0 or 1. func Sub(x, y, borrow uint) (diff, borrowOut uint) { - yb := y + borrow - diff = x - yb - if diff > x || yb < y { - borrowOut = 1 + if UintSize == 32 { + d32, b32 := Sub32(uint32(x), uint32(y), uint32(borrow)) + return uint(d32), uint(b32) } - return + d64, b64 := Sub64(uint64(x), uint64(y), uint64(borrow)) + return uint(d64), uint(b64) } // Sub32 returns the difference of x, y and borrow, diff = x - y - borrow. // The borrow input must be 0 or 1; otherwise the behavior is undefined. // The borrowOut output is guaranteed to be 0 or 1. func Sub32(x, y, borrow uint32) (diff, borrowOut uint32) { - yb := y + borrow - diff = x - yb - if diff > x || yb < y { - borrowOut = 1 - } + diff = x - y - borrow + borrowOut = ((^x & y) | (^(x ^ y) & diff)) >> 31 return } @@ -394,11 +386,8 @@ func Sub32(x, y, borrow uint32) (diff, borrowOut uint32) { // The borrow input must be 0 or 1; otherwise the behavior is undefined. // The borrowOut output is guaranteed to be 0 or 1. func Sub64(x, y, borrow uint64) (diff, borrowOut uint64) { - yb := y + borrow - diff = x - yb - if diff > x || yb < y { - borrowOut = 1 - } + diff = x - y - borrow + borrowOut = ((^x & y) | (^(x ^ y) & diff)) >> 63 return } |