@@ -73,7 +73,7 @@ public final class NBKPrimeSieve: CustomStringConvertible {
73
73
///
74
74
/// - Note: A page contains `1` odd number per bit in `cache`.
75
75
///
76
- /// - Note: The defaults strike balance between size and performance.
76
+ /// - Note: The defaults strike a balance between size and performance.
77
77
///
78
78
public init ( cache: Cache = . KiB( 32 ) , wheel: Wheel = . x07, culls: Culls = . x11) {
79
79
self . cache = cache
@@ -96,11 +96,6 @@ public final class NBKPrimeSieve: CustomStringConvertible {
96
96
self . state. elements
97
97
}
98
98
99
- /// The number of elements sieved per `increment()`.
100
- @inlinable public var stride : UInt {
101
- self . cache. count &<< 1 as UInt // OK, see size
102
- }
103
-
104
99
//=------------------------------------------------------------------------=
105
100
// MARK: Utilities
106
101
//=------------------------------------------------------------------------=
@@ -122,16 +117,15 @@ extension NBKPrimeSieve {
122
117
123
118
/// Sieves the next page of ``NBKPrimeSieve/increment`` number of values.
124
119
@inline ( never) @inlinable public func increment( ) {
125
- precondition ( !self . limit. addingReportingOverflow ( self . stride) . overflow)
126
120
Swift . assert ( ( self . cache. base) . allSatisfy ( { $0. onesComplement ( ) . isZero } ) )
127
121
//=--------------------------------------=
128
- let start = self . limit &+ 00000000002
129
- let limit = self . limit &+ self . stride
122
+ let start = self . limit &+ 0000000000000002
123
+ let limit = self . limit &+ self . cache . count * 2 as UInt // traps max sieve (!)
130
124
var inner = NBK . CyclicIterator ( self . wheel. increments) !
131
125
//=--------------------------------------=
132
126
// mark composites not hit by the wheel
133
127
//=--------------------------------------=
134
- let iteration = 1 &+ NBK . PBI. quotient ( dividing: NBK . ZeroOrMore ( self . limit &>> 1 ) , by: NBK . PowerOf2 ( bitWidth: UInt . self) )
128
+ let iteration = 1 &+ NBK . PBI. quotient ( dividing: NBK . ZeroOrMore ( self . limit &>> 1 as UInt ) , by: NBK . PowerOf2 ( bitWidth: UInt . self) )
135
129
136
130
for pattern in self . culls. patterns {
137
131
var pattern = NBK . CyclicIterator ( pattern) !
@@ -189,13 +183,13 @@ extension NBKPrimeSieve {
189
183
}
190
184
191
185
@inline ( never) @inlinable static func makeInitialState( _ cache: inout Cache , _ wheel: Wheel , _ culls: Culls ) -> State {
192
- Swift . assert ( wheel. primes. first == 000000000000000002 )
193
- Swift . assert ( culls. primes. first != 000000000000000002 )
194
- precondition ( wheel. primes. last! <= culls. primes. last!, " must cull each element in wheel " )
186
+ Swift . assert ( wheel. primes. first == 00000000000000002 )
187
+ Swift . assert ( culls. primes. first != 00000000000000002 )
188
+ precondition ( wheel. primes. last! <= culls. primes. last!, " must cull multiples of each element in wheel " )
195
189
Swift . assert ( wheel. primes [ 1 ... ] . allSatisfy ( culls. primes. contains) )
196
190
Swift . assert ( cache. base. allSatisfy { $0. onesComplement ( ) . isZero } )
197
191
//=--------------------------------------=
198
- let limit = cache. count * 2 - 1 // OK, see size
192
+ let limit = cache. count & * 2 & - 1 // OK, see size
199
193
var outer = NBK . CyclicIterator ( wheel. increments) !
200
194
var inner = NBK . CyclicIterator ( wheel. increments) !
201
195
var state = State ( limit: UInt . max, elements: [ ] )
@@ -311,13 +305,20 @@ extension NBKPrimeSieve {
311
305
312
306
/// ### Development
313
307
///
314
- /// It fits at most `Int.max` bits so the odd number stride fits.
308
+ /// The maximum number of bits is `Int.max + 1`. This is the number of bits
309
+ /// needed to represent each odd number in `0 ... UInt`. The maximum stride
310
+ /// is therefore not representable by `UInt`. But, the sieve is still valid
311
+ /// if there is proper overflow checking past setup.
312
+ ///
313
+ /// - Requires: `words > 0`
315
314
///
316
- /// - Requires: `2 * UInt.bitWidth * words <= UInt.max`
315
+ /// - Requires: `words * UInt.bitWidth * 2 <= UInt.max + 1 `
317
316
///
318
317
@inlinable init ( words: Int ) {
319
- precondition ( words <= ( Int . max / UInt. bitWidth) ,
320
- " the prime sieve's increment must fit in UInt " )
318
+ let limit = ( UInt . max / UInt( UInt . bitWidth * 2 ) ) + 1
319
+ Swift . assert ( limit >= 1 && limit &* UInt ( UInt . bitWidth * 2 ) == 0 as UInt )
320
+ precondition ( UInt ( words) >= 00001 , " prime sieve's stride must be greater than zero " )
321
+ precondition ( UInt ( words) <= limit, " prime sieve's stride must not exceed number of elements in UInt " )
321
322
self . base = Array ( repeating: UInt . max, count: words)
322
323
}
323
324
@@ -329,7 +330,7 @@ extension NBKPrimeSieve {
329
330
@inlinable var count : UInt {
330
331
UInt ( bitPattern: self . base. count) &* UInt ( bitPattern: UInt . bitWidth)
331
332
}
332
-
333
+
333
334
/// The bit at the given `index`.
334
335
@inlinable subscript( index: UInt ) -> Bool {
335
336
let index = NBK . PBI. dividing ( NBK . ZeroOrMore ( index) , by: NBK . PowerOf2 ( bitWidth: UInt . self) )
0 commit comments