Skip to content

Commit f9ec64e

Browse files
committed
[BigInt] Disable custom _Significand and Karatsuba multiplication.
1 parent 4c0d382 commit f9ec64e

File tree

2 files changed

+35
-20
lines changed

2 files changed

+35
-20
lines changed

Sources/BigIntModule/BigInt._Significand.swift

+30-15
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,27 @@
99
//
1010
//===----------------------------------------------------------------------===//
1111

12+
#if true
13+
extension BigInt {
14+
/// The significand of a `BigInt` value, a nonempty collection of the
15+
/// significant digits of that value's magnitude stored in words of type
16+
/// `UInt`.
17+
///
18+
/// The first element of the collection is the lowest word.
19+
@usableFromInline
20+
internal typealias _Significand = [UInt]
21+
}
22+
23+
extension BigInt._Significand {
24+
/// Creates a new significand with the given words.
25+
@inlinable
26+
internal init(_ low: UInt, _ rest: [UInt] = []) {
27+
self = [low]
28+
reserveCapacity(rest.count + 1)
29+
insert(contentsOf: rest, at: 1)
30+
}
31+
}
32+
#else
1233
extension BigInt {
1334
/// The significand of a `BigInt` value, a nonempty collection of the
1435
/// significant digits of that value's magnitude stored in words of type
@@ -26,13 +47,6 @@ extension BigInt {
2647
/// highest.
2748
@usableFromInline
2849
internal var _rest: [UInt]
29-
30-
/// Creates a new significand with a single low word equal to zero.
31-
@inlinable
32-
internal init() {
33-
_low = 0
34-
_rest = []
35-
}
3650

3751
/// Creates a new significand with the given words.
3852
@inlinable
@@ -417,6 +431,7 @@ extension BigInt._Significand {
417431
}
418432

419433
extension BigInt._Significand: Hashable { }
434+
#endif
420435

421436
/// Nota bene:
422437
/// While operations implemented on `BigInt` expect inputs that are normalized
@@ -595,7 +610,7 @@ extension BigInt._Significand {
595610

596611
// @inlinable
597612
internal func multiplying(by other: Self) -> Self {
598-
var result = Self()
613+
var result = Self(0)
599614
result.reserveCapacity(count + other.count)
600615
for i in 0..<other.count {
601616
var temporary = self
@@ -609,25 +624,25 @@ extension BigInt._Significand {
609624
// words) of the lower half of each operand.
610625
// @inlinable
611626
internal func multiplying(by other: Self, karatsubaThreshold: Int) -> Self {
612-
func add(_ lhs: Slice<Self>, _ rhs: Slice<Self>) -> Self {
627+
func add(_ lhs: SubSequence, _ rhs: SubSequence) -> Self {
613628
// Recall that we have a precondition for `Self<C: Collection>(_: C)` that
614629
// the argument not be empty.
615-
if lhs.isEmpty { return rhs.isEmpty ? Self() : Self(rhs) }
630+
if lhs.isEmpty { return rhs.isEmpty ? Self(0) : Self(rhs) }
616631
if rhs.isEmpty { return Self(lhs) }
617632

618633
var result = Self(lhs)
619634
result.add(Self(rhs))
620635
return result
621636
}
622637

623-
func multiply(_ lhs: Slice<Self>, _ rhs: Slice<Self>) -> Self {
638+
func multiply(_ lhs: SubSequence, _ rhs: SubSequence) -> Self {
624639

625640
// Based on Karatsuba's method. For details see:
626641
// <https://mathworld.wolfram.com/KaratsubaMultiplication.html>.
627642

628643
let m = (Swift.max(lhs.count, rhs.count) + 1) / 2
629644
guard m >= karatsubaThreshold else {
630-
if lhs.isEmpty || rhs.isEmpty { return Self() }
645+
if lhs.isEmpty || rhs.isEmpty { return Self(0) }
631646
return Self(lhs).multiplying(by: Self(rhs))
632647
}
633648

@@ -655,7 +670,7 @@ extension BigInt._Significand {
655670
@inlinable
656671
@discardableResult
657672
internal mutating func divide(by other: UInt) -> /* remainder: */ Self {
658-
if other == 1 { return Self() }
673+
if other == 1 { return Self(0) }
659674
var remainder = 0 as UInt
660675
for i in (0..<count).reversed() {
661676
(self[i], remainder) = other.dividingFullWidth((remainder, self[i]))
@@ -706,11 +721,11 @@ extension BigInt._Significand {
706721
other.removeLast(n &- (i &+ 1))
707722
n = i &+ 1
708723
}
709-
guard n > 1 else { return divide(by: other._low) }
724+
guard n > 1 else { return divide(by: other[0]) }
710725
let clz = other[n &- 1].leadingZeroBitCount
711726

712727
var m = count - n
713-
guard let j = lastIndex(where: { $0 != 0 }) else { return Self() }
728+
guard let j = lastIndex(where: { $0 != 0 }) else { return Self(0) }
714729
if m > j &+ 1 {
715730
removeLast(m &- (j &+ 1))
716731
m = j &+ 1

Sources/BigIntModule/BigInt.swift

+5-5
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public struct BigInt {
9191
internal mutating func _normalize() {
9292
guard let i = _significand.firstIndex(where: { $0 != 0 }) else {
9393
_combination = 0
94-
_significand = _Significand()
94+
_significand = _Significand(0)
9595
return
9696
}
9797
assert(_combination != 0)
@@ -163,7 +163,7 @@ extension BigInt: AdditiveArithmetic {
163163
@inlinable
164164
public init() {
165165
_combination = 0
166-
_significand = _Significand()
166+
_significand = _Significand(0)
167167
}
168168

169169
@inlinable
@@ -275,7 +275,7 @@ extension BigInt: SignedNumeric {
275275
let combination =
276276
lhs._signum * rhs._signum * (lhs._exponent + rhs._exponent + 1)
277277
let significand =
278-
lhs._significand.multiplying(by: rhs._significand, karatsubaThreshold: 8)
278+
lhs._significand.multiplying(by: rhs._significand /*, karatsubaThreshold: 8 */)
279279
var result = BigInt(_combination: combination, significand: significand)
280280
result._normalize()
281281
return result
@@ -451,7 +451,7 @@ extension BigInt: BinaryInteger {
451451
var result = lhs._significand.divide(by: rhs._significand)
452452
swap(&result, &lhs._significand)
453453
} else {
454-
lhs._significand = _Significand()
454+
lhs._significand = _Significand(0)
455455
}
456456
lhs._normalize()
457457
}
@@ -682,7 +682,7 @@ extension BigInt {
682682
let signum = Int(bitPattern: words.last!) < 0 ? -1 : 1
683683
guard let exponent = words.firstIndex(where: { $0 != 0 }) else {
684684
_combination = 0
685-
_significand = _Significand()
685+
_significand = _Significand(0)
686686
return
687687
}
688688
_combination = signum * (exponent + 1)

0 commit comments

Comments
 (0)