@@ -252,8 +252,8 @@ public struct DoubleWidth<Base : FixedWidthInteger> :
252
252
let initialOffset = q. leadingZeroBitCount +
253
253
( DoubleWidth . bitWidth - rhs. leadingZeroBitCount) - 1
254
254
255
- // TODO(performance): Use &>> instead here?
256
255
// Start with remainder capturing the high bits of q.
256
+ // (These need to be smart shifts, as initialOffset can be > q.bitWidth)
257
257
var r = q >> Magnitude ( DoubleWidth . bitWidth - initialOffset)
258
258
q <<= Magnitude ( initialOffset)
259
259
@@ -335,8 +335,9 @@ public struct DoubleWidth<Base : FixedWidthInteger> :
335
335
let mid2 = sum ( b. carry, c. carry, d. partial)
336
336
337
337
let low = DoubleWidth < Low > ( ( mid1. partial, a. partial) )
338
- let high = DoubleWidth (
339
- ( High ( mid2. carry + d. carry) , mid1. carry + mid2. partial) )
338
+ let high = DoubleWidth ( (
339
+ High ( mid2. carry + d. carry) , mid1. carry + mid2. partial
340
+ ) )
340
341
341
342
if isNegative {
342
343
let ( lowComplement, overflow) = ( ~ low) . addingReportingOverflow ( 1 )
@@ -372,6 +373,7 @@ public struct DoubleWidth<Base : FixedWidthInteger> :
372
373
return
373
374
}
374
375
376
+ // Shift is larger than this type's bit width.
375
377
if rhs. _storage. high != ( 0 as High ) ||
376
378
rhs. _storage. low >= DoubleWidth . bitWidth
377
379
{
@@ -415,31 +417,31 @@ public struct DoubleWidth<Base : FixedWidthInteger> :
415
417
}
416
418
417
419
public static func &<<= ( lhs: inout DoubleWidth , rhs: DoubleWidth ) {
420
+ // Need to use smart shifts here, since rhs can be > Base.bitWidth
418
421
let rhs = rhs & DoubleWidth ( DoubleWidth . bitWidth - 1 )
419
422
420
423
lhs. _storage. high <<= High ( rhs. _storage. low)
421
- if Base . bitWidth > rhs. _storage. low {
422
- lhs. _storage. high |= High ( extendingOrTruncating: lhs. _storage. low >>
423
- ( numericCast ( Base . bitWidth) - rhs. _storage. low) )
424
- } else {
425
- lhs. _storage. high |= High ( extendingOrTruncating: lhs. _storage. low <<
426
- ( rhs. _storage. low - numericCast( Base . bitWidth) ) )
427
- }
424
+
425
+ let lowInHigh = Base . bitWidth > rhs. _storage. low
426
+ ? lhs. _storage. low >> ( numericCast ( Base . bitWidth) - rhs. _storage. low)
427
+ : lhs. _storage. low << ( rhs. _storage. low - numericCast( Base . bitWidth) )
428
+ lhs. _storage. high |= High ( truncatingIfNeeded: lowInHigh)
429
+
428
430
lhs. _storage. low <<= rhs. _storage. low
429
431
}
430
432
431
433
public static func &>>= ( lhs: inout DoubleWidth , rhs: DoubleWidth ) {
434
+ // Need to use smart shifts here, since rhs can be > Base.bitWidth
432
435
let rhs = rhs & DoubleWidth ( DoubleWidth . bitWidth - 1 )
433
436
434
437
lhs. _storage. low >>= rhs. _storage. low
435
- if Base . bitWidth > rhs. _storage. low {
436
- lhs. _storage. low |= Low ( extendingOrTruncating: lhs. _storage. high <<
437
- numericCast ( numericCast ( Base . bitWidth) - rhs. _storage. low) )
438
- } else {
439
- lhs. _storage. low |= Low ( extendingOrTruncating: lhs. _storage. high >>
440
- numericCast ( rhs. _storage. low - numericCast( Base . bitWidth) ) )
441
- }
442
- lhs. _storage. high >>= High ( extendingOrTruncating: rhs. _storage. low)
438
+
439
+ let highInLow = Base . bitWidth > rhs. _storage. low
440
+ ? lhs. _storage. high << ( numericCast ( Base . bitWidth) - rhs. _storage. low)
441
+ : lhs. _storage. high >> ( rhs. _storage. low - numericCast( Base . bitWidth) )
442
+ lhs. _storage. low |= Low ( truncatingIfNeeded: highInLow)
443
+
444
+ lhs. _storage. high >>= High ( truncatingIfNeeded: rhs. _storage. low)
443
445
}
444
446
445
447
% {
@@ -510,8 +512,10 @@ binaryOperators = [
510
512
511
513
@_transparent
512
514
public var byteSwapped: DoubleWidth {
513
- return DoubleWidth ( ( High ( extendingOrTruncating: low. byteSwapped) ,
514
- Low ( extendingOrTruncating: high. byteSwapped) ) )
515
+ return DoubleWidth ( (
516
+ High ( truncatingIfNeeded: low. byteSwapped) ,
517
+ Low ( truncatingIfNeeded: high. byteSwapped)
518
+ ) )
515
519
}
516
520
}
517
521
0 commit comments