Реализации алгоритмов/Решето Аткина: различия между версиями
Содержимое удалено Содержимое добавлено
Поправки к коду реализаций |
Нет описания правки |
||
Строка 17:
=Реализации=
В приведённых ниже реализациях предприняты следующие шаги, направленные на оптимизацию вычислений:
* Флаги «простое\составное» хранятся упакованными в массив битов (<code>vector<bool></code> для С++, <code>BitSet</code> для Java и т. п.), возвращаемый функцией. Значение ''n''-го бита ''true'' соответствует простому ''n'', ''false'' — составному.
* Умножение на степень двойки производится операцией побитового сдвига (''<<''). Например <code>a << 2</code> вместо <code>4 * a</code>.
* Для уменьшения риска переполнения вычисления ведутся в типе длинное целое (<code>unsigned long long</code> в C++, <code>long</code> в Java); на выходе значения выдаются в заданном целочисленном типе.
Строка 24:
==[[w:C++|C++]]==
<source lang="cpp">
// atkin_sieve.
#include <vector>
namespace AtkinSieve {
}
▲ void getPrimesUpTo (unsigned const limit, Sequence &primes) {
// Числа 2 и 3 — заведомо простые▼
#include "atkin_sieve.h"
if (limit > 2u)▼
primes.push_back(2u);▼
else▼
std::vector<bool> AtkinSieve::getPrimesUpTo (unsigned const limit) {
return;▼
if (limit > 3u)▼
std::vector<bool> sieve(limit);
primes.push_back(3u);▼
for (unsigned
▲ // Предварительное просеивание
▲ for (unsigned long long y2 = 1ull, dy2 = 3ull, n; y2 < limit; y2 += dy2, dy2 += 2ull) {
sieve[n].flip();
▲ sieve[n].flip();
▲ // n = 3x² - y² (при x > y)
▲ n -= y2 << 1ull;
▲ if (n <= limit && n % 12ull == 11ull)
}▼
}
unsigned r = 5u;▼
unsigned r = 5u;
for (unsigned long long r2 = r * r, dr2 = (r << 1ull) + 1ull; r2 < limit; ++r, r2 += dr2, dr2 += 2ull) // Числа 2 и 3 — заведомо простые
▲ for (unsigned number = 5u; number < limit; ++number)
primes.push_back(number);▼
return sieve;
}
</source>
Строка 82 ⟶ 77 :
// main.cpp
#include <iostream>
▲#include "atkin_sieve.hpp"
#include "atkin_sieve.h"
int main () {
std::vector<bool> primes = AtkinSieve::getPrimesUpTo(100u
▲ AtkinSieve::getPrimesUpTo(100u, primes); // Вычисление простых чисел ≤ 100
// Вывод последовательности
for (
return 0;
}
Строка 100 ⟶ 92 :
==[[w:Java|Java]]==
<source lang="java">
// AtkinSieve.java
import java.util.BitSet;
public class AtkinSieve {
public static
BitSet sieve = new BitSet();▼
▲ // Числа 2 и 3 — заведомо простые
// Предварительное просеивание
▲ BitSet sieve = new BitSet();
for (long x2 = 1L, dx2 = 3L; x2 < limit; x2 += dx2, dx2 += 2L)
for (long y2 = 1L, dy2 = 3L, n; y2 < limit; y2 += dy2, dy2 += 2L) {
Строка 145 ⟶ 124 :
for (long mr2 = r2; mr2 < limit; mr2 += r2)
sieve.set((int)mr2, false);
▲ // Числа 2 и 3 — заведомо простые
if (limit >
return sieve;
}
}
Строка 155 ⟶ 136 :
<source lang="java">
// Main.java
import java.util.
public class Main {
public static void main (String []args){
▲ AtkinSieve.getPrimesUpTo(100, primes); // Вычисление простых чисел ≤ 100
// Вывод последовательности
for (int
}
}
|