Первый шаг - понять, что разбить его на блоки произвольного размера - тривиально; и что вам НЕ нужен массив (или битовое поле) для каждого числа. Например, если вас интересуют только числа от 100000 до 110000, то для того, чтобы пометить все числа, которые делятся на 3, как «непростые», вы можете сделать «for( index = 3 * (100000+3-1)/3; index < 110000; index += 3) {
». Для более гибкого примера:
for( value = 2; value < sqrt( block_end_value-1); value++ ) {
for( index = value * (block_state_value+value -1)/value; index < block_end_value; index += value ) {
mark_not_prime(index - block_state_value);
}
}
Второй шаг - понять, что вам не нужно заботиться о каждом числе (а указанное выше for( value = 2; value < sqrt( block_end_value-1); value++)
неэффективно). Например, если вы уже отметили числа, которые делятся на 2, как «непростые», то нет причин беспокоиться о том, делятся ли числа на 4, 6 или 8; и если вы уже отметили числа, которые делятся на 3, как «непростые», то нет причин беспокоиться о том, делятся ли числа на 6, 9 или 12; и ... По сути, вы хотите только проверить, делится ли число на другое простое число. Это означает, что для поиска простых чисел в диапазоне от 100000 до 110000 вы сначала хотите найти простые числа в диапазоне от 0 до sqrt (110000); и если вы хотите найти простые числа в диапазоне от 0 до sqrt (110000), вы хотите найти простые числа в диапазоне от 0 до sqrt (sqrt (110000)); и ....
Третий шаг - понять, что его можно ускорить, копируя повторяющиеся узоры. Вы можете создать 2-битный шаблон (представляющий «делится на 2») и везде копировать эти 2 бита. Таким же образом вы можете создать 6-битный шаблон (представляющий «делится на 2 или 3») и везде копировать эти 6 бит. Таким же образом вы можете создать 39916800-битный шаблон (представляющий "делится на 2, 3, 4, 5, 6, 7, 8, 9, 10 и 11") и скопировать этот 39916800-битный шаблон повсюду. Конечно, ничто не мешает вам предварительно сгенерировать шаблон и сохранить его в коде вашей программы.
Четвертый шаг - понять, что числа, кратные 2, слишком тривиальны для хранения, и, не сохраняя их, вы вдвое уменьшаете потребление памяти всеми таблицами и шаблонами (и любым сохраненным / предварительно сгенерированным шаблоном).
Объединив третий и четвертый шаги, указанные выше; предварительно сгенерированный шаблон, представляющий «делится на 2, 3, 4, 5, 6, 7, 8, 9, 10 и 11», будет стоить 19958400 бит, или около 2,38 МБ. Сама по себе первая часть этого шаблона также может быть использована для поиска простых чисел от 1 до первого простого числа, которое больше 11 (в данном случае это будут числа от 1 до 13).
Пятый шаг - понять, что если у вас уже есть шаблон, вы можете использовать его, чтобы найти "N = the next "not marked yet" prime number
", скопировать существующий шаблон N раз, а затем пометить числа, кратные N, как "непростые"; и в итоге получится более крупный узор. Например; если у вас есть шаблон, представляющий "делится на 2, 3, 4, 5, 6, 7, 8, 9, 10 и 11", вы пропустите 12 (потому что он не является простым в соответствии с существующим шаблоном); скопируйте образец 13 раз, затем пометьте числа, которые делятся на 13, как «не простые» и получите образец, представляющий «делится на 2, 3, 4, 5, 6, 7, 8, 9, 10, 11». , 12 и 13 ".
Шестой шаг - осознать, что как только у вас есть шаблон, достаточно большой для нужного вам диапазона, вы можете заполнить недостающие делители без копирования. Например, если вам нужны только простые числа в диапазоне от 1 до 6227020800; затем вы можете взять образец, представляющий "делится на 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 и 13", а затем отметить числа, которые делятся на простые числа в диапазоне от 14 до 6227020800 как «непростое».
Объединив все вышеперечисленное; если вы хотите найти простые числа в диапазоне от 1000000000 до 11000000000; тогда вы должны начать с поиска простых чисел в диапазоне от 1 до sqrt (11000000000); и для этого вы должны скопировать предварительно сгенерированный шаблон и расширить его до тех пор, пока у вас не будет таблицы, достаточно большой для представления простых чисел в диапазоне от 1 до sqrt (11000000000); затем скопируйте этот расширенный шаблон и заполните отсутствующие числа, чтобы сгенерировать таблицу, представляющую простые числа в диапазоне от 1 до sqrt (11000000000); затем создайте таблицу простых чисел в диапазоне от 1000000000 до 11000000000 и инициализируйте память, скопировав в нее данные из «расширенного предварительно сгенерированного шаблона», затем используйте таблицу простых чисел в диапазоне от 1 до sqrt (11000000000), чтобы найти простые числа, которые еще не были включены в «расширенный предварительно сгенерированный шаблон», чтобы найти числа, которые все еще нужно пометить как «непростые», которые вам понадобятся для создания таблицы для чисел от 1000000000 до 11000000000.
person
Brendan
schedule
11.08.2019