Criando o arquivo HTML
Clique com o botão direito do mouse sobre a area de trabalho e selecione a opção 'Novo' 'Documento de Texto'.Clique duas vezes sobre o arquivo recém criado. O editor de texto 'Bloco de Notas' será aberto.
Digite:
<html>
<body>Números Primos
<div id=listagem>2,3,5,7</div>
</body>
</html>
Clique em 'Arquivo' 'Salvar como...'. Selecione a opção 'Todos os arquivos (*.*)' ao invés de 'Documentos de texto (*.txt)'.Dê o nome de Primos.htm
Feche o 'Bloco de Notas' e exclua o arquivo 'Novo documento de Texto'.
Visualizando e editando o arquivo Criado
Clique duas vezes sobre o icone 'Primos' na Area de Trabalho.O 'Navegador' irá abrir o arquivo criado como se fosse uma página da internet.
Minimize a janela do navegador e clique com o botão direito do mouse sobre o icone 'Primos' e clique em 'Editar'.
O 'Bloco de Notas' abrirá o arquivo.
Digite 'Isso é um teste' antes da linha '</body>'
Pressione 'Ctrl+S' para salvar o arquivo.
Mude para a janela do 'Navegador', e aperte 'F5' para recarregar a 'página'.
Volte para o 'Bloco de Notas', apague a linha 'Isso é um teste', salve, volte para o 'Navegador' e 'recarregue'.
Perceba que voce está 'Programando em HTML'.
Iniciando a Programação
Volte para o 'Bloco de Notas' e escreva:<script>
numerosprimos=[2,3,5];
</script>
acima da linha '</body>'.Isso já é o começo da programação.
A 'tag' 'script' indica ao 'navegador' que o código é para ser executado como javascript, não apenas interpretado como 'HTML'.
O código javascript por enquanto é apenas a delaração de uma variável chamada numerosprimos.
Declarar uma variavel é como instruir o 'navegador' a guardar um espaço.
No caso o espaço que o 'navegador' vai guardar se chama 'numerosprimos'.
No espaço chamado numerosprimos guardamos três valores.
O laço 'for'
Vamos começar a escrever as instruções para o navegador calcular os numeros primos.Para isso vamos usar o laço 'for'.
Para entender como funciona o laço 'for' digite:
for(x=1;x<=7;x++)alert(x);
antes da linha '</script>'.Salve, volte para o navegador e recarregue a pagina.
O navegador exibirá umas mensagens chatas, de 1 a 7.
Isso explica o laço 'for'.
O laço 'for' repete uma instrução (ou uma lista de instruções).
A instrução repetida era a mensagem chata.
Há muito, muito mais a ser falado sobre o laço 'for' mas não é o foco desse tutorial.
Assim que tiver entendido o funcionamento básico do laço 'for' apague a linha do laço for no código.
Os primos até 15
Usando o laço 'for' vamos calcular os numeros primos até 15.Digite:
for(x=2;x<15;x++)
{ flag=true;
if(x>2&&x%2==0)flag=false;
if(x>3&&x%3==0)flag=false;
if(x>5&&x%5==0)flag=false;
if(flag)alert(x+' é primo');
}
antes da linha '</script>'.Salve, volte para o navegador e recarregue a pagina.
Repare que o navegador exibe mensagens informando os números primos até 15.
Vamos entender as instruções que o navegador executou:
A primeira linha é o laço for. Basicamente falamos para o navegador seguir uma lista de instruções de 2 a 15. Os simbolos '{' e '}' (abre chaves e fecha chaves) servem para delimitar a lista de instruções a serem repetidas. No exemplo anterior era apenas uma instrução a ser repetida, então os simbolos '{' e '}' eram opicionais.
Na primeira linha da lista de instruções a serem repetidas 13 vezes há uma declaração de variável e atribuição de valor.
Instruimos o navegador a reservar um espaço chamado 'flag' e colocamos o valor 'true' dentro desse espaço que o navegador reservou para nós.
As próximas linhas instruem o navegador a validar uma 'expressão' através do 'comando if'.
A linha 'if(x>2&&x%2==0)flag=false;' instrui para o navegador:
'Se o valor de x for maior que dois e o resto da divisão de x por dois for zero então atribua o valor false para o espaço flag.
'If' significa 'Se' em inglês.
O operador '&&' significa 'e'.
Se x maior que dois 'e' ...
O operador '%' retorna o resto da divisão.
Cinco dividido por três dá um e sobra dois, então 5%3 é igual a dois.
Os numeros primos são aqueles que são divisíveis apenas por um e por si mesmo.
Os números primos são aqueles que o resto da divisão é zero apenas para o número um e o número em si.
Se o resto da divisão for zero, significa que o número é divisivel.
Nove dividido por três dá três e sobra zero.
Dentro do if usa-se '==' para comparar a igualdade.
O simbolo '=' sozinho significa atribuição de valor.
Então novamente,
A segunda linha da lista de instruções a serem repetidas 13 vezes instrui ao navegador:
'SE'( x é maior que dois 'e' x é divisível por dois ) então atribua o valor false para o espaço flag.
Essa linha se repete para o número três e cinco.
Então se o número x (que começa em dois e vai até catorze) for divisivel por dois ou três ou cinco então o espaço 'flag' vai conter o valor 'false'.
A ultima linha da lista de instruções a serem repetidas 13 vezes instrui ao navegador:
Se o valor do espaço flag for verdadeiro então exiba uma mensagem informando que x é primo.
Os primos até 1000
Mas os números primos não são só aqueles que não são divisíveis por dois e três e cinco.Por exmplo o número 121, não é primo.
Não é divisível por dois, nem por três, nem por cinco, nem por sete... mas é divisível por onze.
11x11 == 121
121%11==0
Então para verificarmos se o número x é impar temos que testar se ele é divisível por todos os números primos não maiores que a raiz quadrada dele.
Nós não... o navegador.
Vamos instruir o navegador:
substitua o laço for por
for(x=7;x<1000;x+=2)
{ flag=true;
for(y=0;y<numerosprimos.length;y++)if(x%numerosprimos[y]==0)flag=false;
if(flag)numerosprimos.push(x);
}
document.getElementById('listagem').innerHTML=numerosprimos;
Salve, volte para o navegador e recarregue a pagina.Repare que o navegador exibe uma lista com os números primos até 1000.
Vamos entender as instruções que o navegador executou:
A primeira linha é um 'laço for' que vai de 7 até 1000.
O resto das instruções (exceto a última) serão executadas 496 vezes.
Esse laço instrui o navegador a ir do 7 até o 1000 de dois em dois.
A primeira linha da lista de instruções do laço atribui o valor true à variável flag.
A segunda linha da lista de instruções é um laço com uma instrução condicional.
Podemos entender como:
'Para o y valendo zero até y valendo o tamanho do vetor numerosprimos, com o y incrementando de um em um: se o resto da divisão de x pelo elemento y do vetor numerosprimos for zero então atribua o valor false para a variável flag.'
Há uma novidade nesse laço for, ele é repetido um número variável de vezes.
A expressão 'numerosprimos.length' retorna um valor que varia durante a execução do código.
O espaço 'numerosprimos' foi declarado como um tipo especial de espaço.
Ele é um vetor.
Inicialmente foram ocupados três espaços, mas durante e execução do programa mais espaços vão sendo ocupados.
Sendo assim, na primeira das 496 vezes que essa instrução é executada o y vai de zero até 2 porque o vetor numerosprimos tem três posições ocupadas, a posição zero é ocupada com o valor 2, a posição um é ocupada com o valor 3 e a posição dois é ocupada com o valor 5.
Sobre o vetor numerosprimos, logo após sua inicialização podemos dizer que:
numerosprimos.length==3 (seu tamanho é 3)
numerosprimos[0]==2
numerosprimos[1]==3
numerosprimos[2]==5
Continuando nessa instrução ao navegador que é composta de um laço for, um comando if e uma atribuição de valor:
Se o resto da divisão do valor x (que varia de 7 até 1000) pelo valor numerosprimos[y] (que varia de 2 até o maior número primo armazenado no vetor numerosprimos) for zero então atribua o valor false à variável flag.
Ou seja:
Se o valor x é divisivel por algum dos números primos já encontados então o valor de flag será false.
A última instrução da lista de instruções que é repetida 496 vezes pode ser entendida como:
Se o valor da variável flag for true então adicione o valor de x no final do vetor numerosprimos.
Por que se passou por todos no números primos e não atribuiu o valor false a variável flag é por que x é um número primo.
A última instrução não está dentro de nenhum laço e só é executada uma vez.
Ela instrui o navegador a exibir dentro da div chamada listagem os valores encontrados e armazenados no vetor numerosprimos.
Final Source
<html>
<body>
Números Primos
<div id=listagem>2,3,5,7</div>
<script>
numerosprimos=[2,3,5];
for(x=7;x<1000;x+=2)
{ flag=true;
for(y=0;y<numerosprimos.length;y++)if(x%numerosprimos[y]==0)flag=false;
if(flag)numerosprimos.push(x);
}
document.getElementById('listagem').innerHTML=numerosprimos;
</script>
</body>
</html>
Não maiores que a raiz quadrada
O que foi explanado até aqui está certo mas pode ser melhorado.Há um desperdício de processamento.
O 'laço for' de dentro do 'laço for' principal pode ser melhorado.
Da maneira como está ele testa se o numero é primo atravéz de consecutivas operações de 'resto da divisão'. Só que ele está testando demais da conta.
Vamos tomar por exemplo o número 127 que é primo:
Da maneira como está sendo feito, o navegador irá testar se o número 127 é primo testando se ele é divisível por 2 ou 3 ou 5 ou 7 ou 11 ou 13 ou 17 ou 19 ou 23 ou 29 ou 31 ou 37 ou 41 ou 43 ou 47 ou 53 ou 59 ou 61 ou 67 ou 71 ou 73 ou 79 ou 83 ou 89 ou 97 ou 101 ou 103 ou 107 ou 109 ou 113.
O navegador poderia testar apenas até o número 13.
Não existe a possibilidade de um número x ser divisível por um número y maior que sua raiz quadrada se não foi encontrado nenhum divisor de x menor que a raiz quadrada.
Por que um produto de y e z (maiores que a raiz quadrada de x) só pode resultar em um número maior que x.
Na prática, para melhorar bastante a performance do código basta substituir 'y<numerosprimos.length' por 'numerosprimos[y]*numerosprimos[y]<=x'.
O 'laço for' de dentro ficará:
for(y=0;numerosprimos[y]*numerosprimos[y]<=x;y++)if(x%numerosprimos[y]==0)flag=false;
Mais uma melhoria
Ainda podemos evitar processamentos desnecessários.No caso de um número não primo como por exemplo 81 o navegador irá testar se é divisível por todos o números primos não maiores que sua raiz quadrada: 2,3,5,7
Só que se já testou a divisão por três e marcou a variável flag como false não é nescessário testar a divisão por 5 e 7.
Nesse caso são apenas dois testes mas para números maiores são mais testes desnecessários.
Vamos alterar de 'numerosprimos[y]*numerosprimos[y]<=x' para 'flag&&numerosprimos[y]*numerosprimos[y]<=x'.
O 'laço for' de dentro ficará:
for(y=0;flag&&numerosprimos[y]*numerosprimos[y]<=x;y++)if(x%numerosprimos[y]==0)flag=false;
E outra melhoria...
Não precisamos testar se os números são divisíveis por dois porque o laço for começa em 7 e vai de dois em dois.Vamos substituir 'for(y=0;' por 'for(y=1;' assim a bateria de testes para descubrir se x é divisível por todos os primos não maiores que sua raiz quadrada começa pelo número 3 (que é o elemento numerosprimos[1]).
O 'laço for' de dentro ficará:
for(y=1;flag&&numerosprimos[y]*numerosprimos[y]<=x;y++)if(x%numerosprimos[y]==0)flag=false;
Os primos até 100.000
Basta mudar de 1000 para 100000 no laço 'for'.E ter um pouco de paciência.
Não recomendo mudar para um milhão pois demora muito, sobrecarrega o navegador...