@@ -73,6 +73,9 @@ using uint128_t = boost::multiprecision::uint128_t;
73
73
Integer delta_;
74
74
Integer left_;
75
75
Integer right_;
76
+
77
+ // The adjusted value of left that represent the beginning value of the bitset based off the next spoke in the wheel after left_
78
+ Integer mod_left_;
76
79
77
80
OutputIterator resultant_primes_;
78
81
@@ -143,17 +146,33 @@ void IntervalSieve<Integer, OutputIterator>::Settdlimit() noexcept
143
146
template <typename Integer, typename OutputIterator>
144
147
void IntervalSieve<Integer, OutputIterator>::SeiveLength(const Integer d) noexcept
145
148
{
146
- Integer r {left_ % d};
147
- Integer start {0 };
148
-
149
- if (r != 0 )
149
+ // Find the first multiple of d in the bitset to use as the entry point
150
+ Integer current_multiple {mod_left_};
151
+ Integer current_spoke {mod_left_};
152
+ std::size_t i {};
153
+ while (current_multiple % d != 0 )
150
154
{
151
- start = d - r;
155
+ ++current_multiple;
156
+ if (current_spoke < current_multiple)
157
+ {
158
+ current_spoke = w_.Next (current_spoke);
159
+ ++i;
160
+ }
152
161
}
153
162
154
- for (Integer i {start}; i >= 0 && i < b_.size (); i += d )
163
+ while (i < b_.size ())
155
164
{
156
- b_.clear (static_cast <std::size_t >(i));
165
+ if (current_multiple == current_spoke)
166
+ {
167
+ b_.clear (i);
168
+ }
169
+
170
+ current_multiple += d;
171
+ while (current_spoke < current_multiple)
172
+ {
173
+ current_spoke = w_.Next (current_spoke);
174
+ ++i;
175
+ }
157
176
}
158
177
}
159
178
@@ -172,11 +191,11 @@ void IntervalSieve<Integer, OutputIterator>::Sieve() noexcept
172
191
}
173
192
174
193
// Sieve with pre-computed (or small) primes and then use the wheel for the remainder
175
- std::size_t i {};
194
+ // Start with the first prime being 7 as the wheel basis (2,3,5) is not represented in b_
195
+ std::size_t i {2 };
176
196
Integer j;
177
197
if (plimit_ <= pss_.prime .back ())
178
198
{
179
- SeiveLength (static_cast <Integer>(2 ));
180
199
for (; pss_.prime [i] < primes_range; ++i)
181
200
{
182
201
SeiveLength (pss_.prime [i]);
@@ -187,6 +206,7 @@ void IntervalSieve<Integer, OutputIterator>::Sieve() noexcept
187
206
188
207
else
189
208
{
209
+ ++i; // linear_sieve begins with 2 whereas pss_.prime begins with 3
190
210
primes_.resize (static_cast <std::size_t >(prime_approximation (right_)));
191
211
linear_sieve (primes_range, primes_.begin ());
192
212
@@ -207,12 +227,14 @@ void IntervalSieve<Integer, OutputIterator>::Sieve() noexcept
207
227
template <typename Integer, typename OutputIterator>
208
228
decltype (auto ) IntervalSieve<Integer, OutputIterator>::WriteOutput() noexcept
209
229
{
210
- for (std::size_t i {left_ % 2 == 0 ? 1 : 0 }; i < b_.size (); i += 2 )
230
+ Integer current_spoke {mod_left_};
231
+ for (std::size_t i {}; i < b_.size (); ++i)
211
232
{
212
233
if (b_[i])
213
234
{
214
- *resultant_primes_++ = left_ + i ;
235
+ *resultant_primes_++ = current_spoke ;
215
236
}
237
+ current_spoke = w_.Next (current_spoke);
216
238
}
217
239
return resultant_primes_;
218
240
}
@@ -223,7 +245,13 @@ decltype(auto) IntervalSieve<Integer, OutputIterator>::WriteOutput() noexcept
223
245
template <typename Integer, typename OutputIterator>
224
246
bool IntervalSieve<Integer, OutputIterator>::Psstest(const std::size_t pos) noexcept
225
247
{
226
- const Integer n {static_cast <Integer>(left_ + pos)};
248
+ // Convert a bitset position (pos) into the corresponding numerical value using the wheel
249
+ Integer n {mod_left_};
250
+ for (std::size_t i {}; i < pos; ++i)
251
+ {
252
+ n = w_.Next (n);
253
+ }
254
+
227
255
const Integer exponent {(n - 1 ) / 2 };
228
256
const std::int_fast64_t nmod8 = static_cast <std::int_fast64_t >(n % 8 );
229
257
@@ -283,8 +311,9 @@ void IntervalSieve<Integer, OutputIterator>::Setup(const Integer left, const Int
283
311
left_ = left;
284
312
right_ = right;
285
313
delta_ = right_ - left_;
314
+ mod_left_ = w_.Next (left_ - 1 ); // Subtract one in the case that left_ resides on a spoke
286
315
287
- b_.resize (static_cast <std::size_t >(delta_));
316
+ b_.resize (static_cast <std::size_t >(delta_) * w_. PrimeRatio () );
288
317
b_.reset ();
289
318
Settdlimit ();
290
319
Sieve ();
0 commit comments