summaryrefslogtreecommitdiff
path: root/src/math/bits/bits.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/math/bits/bits.go')
-rw-r--r--src/math/bits/bits.go49
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
}