Lista Dos Numeros Primos - Lista Dos 100 Primeiros Numeros Primos Você Conhece Os Números
Lista Dos 100 Primeiros Numeros Primos Você Conhece Os Números

Como gerar uma lista de números primos na prática

Gerar uma lista de números primos parece simples no papel, mas a coisa desandava rápido quando você precisava ir além dos primeiros milhares. Eu já passei sufoco num projeto de criptografia antiga onde o requisito era ter todos os primos abaixo de 10 milhões para testes de segurança. A abordagem ingênua que quase todo mundo tenta primeiro — verificar cada número individualmente com divisão sucessiva — quebra miseravelmente nessa escala. Para 10 milhões de candidatos, esse método bobeiro leva horas. Eu estava há 3 horas rodando quando percebi que estava fazendo besteira. O Crivo de Eratóstenes é o caminho real. A ideia é elementar: você marca todos os múltiplos de cada primo encontrado, e o que sobrar não marcado é primo. A complexidade é O(n log log n), o que para 10 milhões significa basicamente segundos em qualquer máquina razoável. Implementação direta em Python leva uns 15 minutos de código e roda em menos de 3 segundos num notebook comum.

Construindo sua lista dos numeros primos

A versão mais pura do crivo aloca um array booleano do tamanho do limite desejado. Começa marcando 0 e 1 como não primos, depois itera de 2 até a raiz quadrada do limite. Para cada número ainda marcado como primo, marca todos os seus múltiplos a partir do seu quadrado — não precisa começar do dobro porque múltiplos menores já foram tratados por primos anteriores. Essa otimização do ponto de partida já reduz o trabalho em cerca de metade comparado à versão didática que aparece em muitos livros. O problema é que o crivo clássico gasta memória proporcional ao limite. Para 10 milhões de inteiros, um array booleano puro consome uns 10 MB, o que é tranquilo. Mas se você precisar de primos até 1 bilhão, o array único exige cerca de 1 GB de memória RAM. Aí entra o crivo segmentado, que processa o intervalo em blocos menores. Você ainda usa os primos até a raiz quadrada do limite total para fazer as marcações, mas a lista principal cabe em memória porque é tratada por segmentos. Para 1 bilhão com blocos de 1 MB, o consumo cai para algo em torno de 2-3 MB no total, e a velocidade fica numa faixa razoável — uns 10 a 15 segundos em Python, menos em C.

Uma coisa que muita gente não percebe: se o objetivo é só listar os primos sem fatorar números específicos depois, o crivo é imbatível. Mas se você precisa testar primalidade de números grandes isolados — tipo verificar se um número de 50 dígitos é primo — o crivo não serve de nada. Aí você migra para testes probabilísticos como Miller-Rabin, que são exponencialmente mais eficientes para números desse porte. Use o crivo para listas densas em intervalos pequenos. Use Miller-Rabin para primalidade de números esparsos e grandes. Misturar as duas coisas sem critério é erro comum. Também vale lembrar que existem listas prontas e confiáveis na internet. O site PrimePages (primenumbers.gov) mantém tabelas atualizadas, e o OEIS (A000040) tem a sequência completa com mais de 1,5 milhão de entradas disponíveis para download em formato de texto puro. Se você só precisa consultar e não implementar, baixar uma lista pré-computada é trivial. O problema é que arquivos enormes — acima de 100 milhões de primos — podem pesar centenas de megabytes, e processá-los em linguagens interpretadas fica lento por causa do overhead de parse. Em C ou Go, lendo diretamente do disco, o throughput é na casa dos milhões deentries por segundo.

👉 Clique no botão abaixo para saber mais sobre o assunto!

Se sua aplicação exige distribuição uniforme de primos para gerar chaves ou hashes, prestar atenção na densidade ajuda. O teorema dos números primos diz que a quantidade de primos até N é aproximadamente N / ln(N). Isso significa que entre 1 milhão e 2 milhões há cerca de 78.000 primos, mas entre 1 bilhão e 1 bilhão e meio a queda para uns 50.000. Se você precisa de um primo randômico dentro de um intervalo grande, simplesmente testar números ímpares consecutivos a partir de um ponto aleatório encontra um primo em média a cada ln(N) tentativas. Para N = 10^9, isso dá roughly 20 testes de primalidade, o que é praticamente instantâneo com Miller-Rabin. O único ponto fraco real do crivo de Eratóstenes é a necessidade de memória contígua para a versão não segmentada. Em ambientes embarcados ou com restrições severas de RAM, essa limitação pode ser decisiva. Nesse caso, o crivo segmentado resolve, mas com um custo extra de implementação. Não é complicado, mas exige cuidado com os índices de cada segmento para não errar as marcações. Um erro de off-by-one aqui gera primos faltando na lista sem nenhum aviso — o código roda, produz resultado, e o resultado está errado. Debugar isso leva mais tempo do que implementar corretamente desde o início.

Quando não usar o crivo

Se o seu cenário envolve números maiores que 10^12, o crivo mesmo segmentado não escala bem. A memória necessária cresce linearmente com o tamanho do segmento, e o tempo de marcação dos múltiplos também. Para esses casos, testes de primalidade determinísticos como AKS (embora teórico demais na prática) ou combinações de Miller-Rabin com bases fixas para faixas conhecidas são mais adequados. O campo de criptografia RSA, por exemplo, trabalha com primos de centenas de dígitos, e ninguém usa crivo nisso — o tempo seria proibitivo. Outro detalhe prático: se você só precisa dos primeiros N primos, não do limite superior, uma do crivo chamada "sieve of Atkins" tem complexidade teórica melhor (O(n / log log n)), mas na prática raramente vence o Eratóstenes por causa das constantes maiores e da lógica mais. A diferença real de performance é marginal na maioria das implementações, e o código do Atkins é muito mais propenso a bugs. Fique com Eratóstenes a menos que tenha benchmark concreto mostrando contrário no seu ambiente.

Resumo do que funciona: Use crivo de Eratóstenes para intervalos até quelques centaines de millions. Use crivo segmentado para bilhões. Use Miller-Rabin para números isolados grandes. E verifique sempre com uma lista conhecida antes de confiar no seu código — pelo menos os primeiros 1000 primos, que você pode checar contra tabelas públicas em segundos.