@@ -314,8 +314,8 @@ public struct DoubleWidth<Base : FixedWidthInteger> :
314
314
let initialOffset = q. leadingZeroBitCount +
315
315
( DoubleWidth . bitWidth - rhs. leadingZeroBitCount) - 1
316
316
317
- // TODO(performance): Use &>> instead here?
318
317
// Start with remainder capturing the high bits of q.
318
+ // (These need to be smart shifts, as initialOffset can be > q.bitWidth)
319
319
var r = q >> Magnitude ( DoubleWidth . bitWidth - initialOffset)
320
320
q <<= Magnitude ( initialOffset)
321
321
@@ -396,8 +396,9 @@ public struct DoubleWidth<Base : FixedWidthInteger> :
396
396
let mid2 = sum ( b. carry, c. carry, d. partial)
397
397
398
398
let low = DoubleWidth < Low > ( ( mid1. partial, a. partial) )
399
- let high = DoubleWidth (
400
- ( High ( mid2. carry + d. carry) , mid1. carry + mid2. partial) )
399
+ let high = DoubleWidth ( (
400
+ High ( mid2. carry + d. carry) , mid1. carry + mid2. partial
401
+ ) )
401
402
402
403
if isNegative {
403
404
let ( lowComplement, overflow) = ( ~ low) . addingReportingOverflow ( 1 )
@@ -433,6 +434,7 @@ public struct DoubleWidth<Base : FixedWidthInteger> :
433
434
return
434
435
}
435
436
437
+ // Shift is larger than this type's bit width.
436
438
if rhs. _storage. high != ( 0 as High ) ||
437
439
rhs. _storage. low >= DoubleWidth . bitWidth
438
440
{
@@ -476,32 +478,30 @@ public struct DoubleWidth<Base : FixedWidthInteger> :
476
478
}
477
479
478
480
public static func &<<= ( lhs: inout DoubleWidth , rhs: DoubleWidth ) {
481
+ // Need to use smart shifts here, since rhs can be > Base.bitWidth
479
482
let rhs = rhs & DoubleWidth ( DoubleWidth . bitWidth - 1 )
480
483
481
484
lhs. _storage. high <<= High ( rhs. _storage. low)
482
- if Base . bitWidth > rhs. _storage. low {
483
- lhs. _storage. high |= High ( truncatingIfNeeded: lhs. _storage. low >>
484
- ( numericCast ( Base . bitWidth) - rhs. _storage. low) )
485
- } else {
486
- lhs. _storage. high |= High ( truncatingIfNeeded: lhs. _storage. low <<
487
- ( rhs. _storage. low - numericCast( Base . bitWidth) ) )
488
- }
485
+
486
+ let lowInHigh = Base . bitWidth > rhs. _storage. low
487
+ ? lhs. _storage. low >> ( numericCast ( Base . bitWidth) - rhs. _storage. low)
488
+ : lhs. _storage. low << ( rhs. _storage. low - numericCast( Base . bitWidth) )
489
+ lhs. _storage. high |= High ( truncatingIfNeeded: lowInHigh)
490
+
489
491
lhs. _storage. low <<= rhs. _storage. low
490
492
}
491
493
492
494
public static func &>>= ( lhs: inout DoubleWidth , rhs: DoubleWidth ) {
495
+ // Need to use smart shifts here, since rhs can be > Base.bitWidth
493
496
let rhs = rhs & DoubleWidth ( DoubleWidth . bitWidth - 1 )
494
497
495
498
lhs. _storage. low >>= rhs. _storage. low
496
- if Base . bitWidth > rhs. _storage. low {
497
- lhs. _storage. low |= Low (
498
- truncatingIfNeeded:
499
- lhs. _storage. high << ( numericCast ( Base . bitWidth) - rhs. _storage. low) )
500
- } else {
501
- lhs. _storage. low |= Low (
502
- truncatingIfNeeded: lhs. _storage. high >>
503
- ( rhs. _storage. low - numericCast( Base . bitWidth) ) )
504
- }
499
+
500
+ let highInLow = Base . bitWidth > rhs. _storage. low
501
+ ? lhs. _storage. high << ( numericCast ( Base . bitWidth) - rhs. _storage. low)
502
+ : lhs. _storage. high >> ( rhs. _storage. low - numericCast( Base . bitWidth) )
503
+ lhs. _storage. low |= Low ( truncatingIfNeeded: highInLow)
504
+
505
505
lhs. _storage. high >>= High ( truncatingIfNeeded: rhs. _storage. low)
506
506
}
507
507
@@ -573,8 +573,10 @@ binaryOperators = [
573
573
574
574
@_transparent
575
575
public var byteSwapped: DoubleWidth {
576
- return DoubleWidth ( ( High ( truncatingIfNeeded: low. byteSwapped) ,
577
- Low ( truncatingIfNeeded: high. byteSwapped) ) )
576
+ return DoubleWidth ( (
577
+ High ( truncatingIfNeeded: low. byteSwapped) ,
578
+ Low ( truncatingIfNeeded: high. byteSwapped)
579
+ ) )
578
580
}
579
581
}
580
582
0 commit comments