@@ -332,35 +332,30 @@ func Len64(x uint64) (n int) {
332
332
// The carry input must be 0 or 1; otherwise the behavior is undefined.
333
333
// The carryOut output is guaranteed to be 0 or 1.
334
334
func Add (x , y , carry uint ) (sum , carryOut uint ) {
335
- yc := y + carry
336
- sum = x + yc
337
- if sum < x || yc < y {
338
- carryOut = 1
335
+ if UintSize == 32 {
336
+ s32 , c32 := Add32 (uint32 (x ), uint32 (y ), uint32 (carry ))
337
+ return uint (s32 ), uint (c32 )
339
338
}
340
- return
339
+ s64 , c64 := Add64 (uint64 (x ), uint64 (y ), uint64 (carry ))
340
+ return uint (s64 ), uint (c64 )
341
341
}
342
342
343
343
// Add32 returns the sum with carry of x, y and carry: sum = x + y + carry.
344
344
// The carry input must be 0 or 1; otherwise the behavior is undefined.
345
345
// The carryOut output is guaranteed to be 0 or 1.
346
346
func Add32 (x , y , carry uint32 ) (sum , carryOut uint32 ) {
347
- yc := y + carry
348
- sum = x + yc
349
- if sum < x || yc < y {
350
- carryOut = 1
351
- }
347
+ sum64 := uint64 (x ) + uint64 (y ) + uint64 (carry )
348
+ sum = uint32 (sum64 )
349
+ carryOut = uint32 (sum64 >> 32 )
352
350
return
353
351
}
354
352
355
353
// Add64 returns the sum with carry of x, y and carry: sum = x + y + carry.
356
354
// The carry input must be 0 or 1; otherwise the behavior is undefined.
357
355
// The carryOut output is guaranteed to be 0 or 1.
358
356
func Add64 (x , y , carry uint64 ) (sum , carryOut uint64 ) {
359
- yc := y + carry
360
- sum = x + yc
361
- if sum < x || yc < y {
362
- carryOut = 1
363
- }
357
+ sum = x + y + carry
358
+ carryOut = ((x & y ) | ((x | y ) &^ sum )) >> 63
364
359
return
365
360
}
366
361
@@ -370,35 +365,29 @@ func Add64(x, y, carry uint64) (sum, carryOut uint64) {
370
365
// The borrow input must be 0 or 1; otherwise the behavior is undefined.
371
366
// The borrowOut output is guaranteed to be 0 or 1.
372
367
func Sub (x , y , borrow uint ) (diff , borrowOut uint ) {
373
- yb := y + borrow
374
- diff = x - yb
375
- if diff > x || yb < y {
376
- borrowOut = 1
368
+ if UintSize == 32 {
369
+ d32 , b32 := Sub32 (uint32 (x ), uint32 (y ), uint32 (borrow ))
370
+ return uint (d32 ), uint (b32 )
377
371
}
378
- return
372
+ d64 , b64 := Sub64 (uint64 (x ), uint64 (y ), uint64 (borrow ))
373
+ return uint (d64 ), uint (b64 )
379
374
}
380
375
381
376
// Sub32 returns the difference of x, y and borrow, diff = x - y - borrow.
382
377
// The borrow input must be 0 or 1; otherwise the behavior is undefined.
383
378
// The borrowOut output is guaranteed to be 0 or 1.
384
379
func Sub32 (x , y , borrow uint32 ) (diff , borrowOut uint32 ) {
385
- yb := y + borrow
386
- diff = x - yb
387
- if diff > x || yb < y {
388
- borrowOut = 1
389
- }
380
+ diff = x - y - borrow
381
+ borrowOut = ((^ x & y ) | (^ (x ^ y ) & diff )) >> 31
390
382
return
391
383
}
392
384
393
385
// Sub64 returns the difference of x, y and borrow: diff = x - y - borrow.
394
386
// The borrow input must be 0 or 1; otherwise the behavior is undefined.
395
387
// The borrowOut output is guaranteed to be 0 or 1.
396
388
func Sub64 (x , y , borrow uint64 ) (diff , borrowOut uint64 ) {
397
- yb := y + borrow
398
- diff = x - yb
399
- if diff > x || yb < y {
400
- borrowOut = 1
401
- }
389
+ diff = x - y - borrow
390
+ borrowOut = ((^ x & y ) | (^ (x ^ y ) & diff )) >> 63
402
391
return
403
392
}
404
393
0 commit comments