Этот вопрос немного скуп на низкой стороне в определении того, что такое «большое количество» есть и принимает что он начинается всего с миллиона, для которого работает current answer; однако он использует довольно много памяти, как в одном 8-байтовом номере (двойной реальный из 64 бит) для каждого просеиваемого элемента и еще одного 8-байтового числа для каждого найденного простого. Этот ответ не будет работать для «больших чисел», скажем, около 250 миллионов и выше, поскольку он будет превышать объем памяти, доступный для исполняющей машины JavaScript.
Следующий код JavaScript, реализующий «бесконечное» (неограниченное) Страница Сегментированное сито Эратосфена, преодолевает эту проблему, поскольку он использует только один бит-бит 16-ти килобайтного сегментированного просеивающего буфера (один бит представляет собой одно потенциальное простое число) и только использует память для базовых простых чисел до квадратного корня из текущего наибольшего числа в текущем сегменте страницы, причем фактические найденные простые числа перечислены в порядке, не требуя хранения; Кроме экономии времени лишь просеивание нечетных композитов в качестве единственного даже простого числа 2:
var SoEPgClass = (function() {
function SoEPgClass() {
this.bi = -1; // constructor resets the enumeration to start...
}
SoEPgClass.prototype.next = function() {
if (this.bi < 1) {
if (this.bi < 0) {
this.bi++;
this.lowi = 0; // other initialization done here...
this.bpa = [];
return 2;
} else { // bi must be zero:
var nxt = 3 + 2 * this.lowi + 262144; //just beyond the current page
this.buf = [];
for (var i = 0; i < 2048; i++) this.buf.push(0); // faster initialization 16 KByte's:
if (this.lowi <= 0) { // special culling for first page as no base primes yet:
for (var i = 0, p = 3, sqr = 9; sqr < nxt; i++, p += 2, sqr = p * p)
if ((this.buf[i >> 5] & (1 << (i & 31))) === 0)
for (var j = (sqr - 3) >> 1; j < 131072; j += p)
this.buf[j >> 5] |= 1 << (j & 31);
} else { // other than the first "zeroth" page:
if (!this.bpa.length) { // if this is the first page after the zero one:
this.bps = new SoEPgClass(); // initialize separate base primes stream:
this.bps.next(); // advance past the only even prime of 2
this.bpa.push(this.bps.next()); // keep the next prime (3 in this case)
}
// get enough base primes for the page range...
for (var p = this.bpa[this.bpa.length - 1], sqr = p * p; sqr < nxt;
p = this.bps.next(), this.bpa.push(p), sqr = p * p);
for (var i = 0; i < this.bpa.length; i++) { //for each base prime in the array
var p = this.bpa[i];
var s = (p * p - 3) >> 1; //compute the start index of the prime squared
if (s >= this.lowi) // adjust start index based on page lower limit...
s -= this.lowi;
else { //for the case where this isn't the first prime squared instance
var r = (this.lowi - s) % p;
s = (r != 0) ? p - r : 0;
}
//inner tight composite culling loop for given prime number across page
for (var j = s; j < 131072; j += p) this.buf[j >> 5] |= 1 << (j & 31);
}
}
}
}
//find next marker still with prime status
while (this.bi < 131072 && this.buf[this.bi >> 5] & (1 << (this.bi & 31))) .bi++;
if (this.bi < 131072) // within buffer: output computed prime
return 3 + ((this.lowi + this.bi++) * 2);
else { // beyond buffer range: advance buffer
this.bi = 0;
this.lowi += 131072;
return this.next(); // and recursively loop just once to make a new page buffer
}
};
return SoEPgClass;
})();
Приведенных выше код может быть использован для подсчета простых чисел до заданного предела с помощью следующего кода JavaScript:
window.onload = function() {
var elpsd = -new Date().getTime();
var top_num = 1000000000;
var cnt = 0;
var gen = new SoEPgClass();
while (gen.next() <= top_num) cnt++;
elpsd += (new Date()).getTime();
document.getElementById('content')
.innerText = 'Found ' + cnt + ' primes up to ' + top_num + ' in ' + elpsd + ' milliseconds.';
};
Если вышеуказанные два фрагмента кода JavaScript помещаются в файл с именем app.js в той же папке, что и следующий HTML-код, который называется any.HTML, вы будете иметь возможность запускать код в вашем браузере, открыв файл HTML в нем:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Page Segmented Sieve of Eratosthenes in JavaScript</title>
<script src="app.js"></script>
</head>
<body>
<h1>Page Segmented Sieve of Eratosthenes in JavaScript.</h1>
<div id="content"></div>
</body>
</html>
Этот код может просеивать на один миллиард диапазона несколько 10-х секунд при запуске на исполнение двигателя JavaScript используя компиляцию Just-In-Time (JIT), такую как движок V8 от Google Chrome. Дальнейшие успехи могут быть достигнуты за счет использования экстремальной факторизации колес и предварительной отбраковки буферов страниц наименьших базовых простых чисел, и в этом случае объем выполненной работы может быть сокращен еще на четыре раза, что означает, что количество простых чисел можно подсчитать до миллиарда в несколько секунд (подсчет не требует перечисления, как используется здесь, а скорее может использовать таблицы подсчета счетчика бит на буфера сегментов страницы напрямую), хотя ценой повышенной сложности кода.
Вы делаете ваше сито намеренно медленнее путем использования 'массива # indexOf' и' Массив # splice' – Alexander
Ваша функция возвращает [[2], 3] вместо [2,3] на входе 5 ... – loxxy