Qual o melhor modo de testar se um número é primo?

Gente meu objetivo era testar de 1 a 2 milhões quais são os primos então o objetivo é encontrar o modo mais rápido para a máquina processar julgando se o número é primo ou não meu método é esse:

public static boolean primos(long x){ int z=0; boolean res; for(long i=1;i<=x;i++)if((x%i)==0)z++;//adiciona o numero de divisores perfeitos para x return((z==2)? true:false);//se é divisivel por apenas 2 números(é primo:1 e ele mesmo)retorna seu valor }
Existe algum pacote que teste mais rápido pois do modo que estou fazendo vai demorar muito! pra terminar a execução! :?
:x

Olá
Tem esse link, agora não sei qto mais rápido ele é, pelo
que vi ele busca todos os primos…

Espero ter ajudado
Flwssss

Teve uma discussão sobre isso a pouco tempo neste fórum:
http://www.guj.com.br/posts/list/124189.java#671342

Não é o mesmo do outro tópico!
O problema é que aki eu não tenho que calcular os fatores primos mais tenho de somar todos os primos existentes de 1 a 2000000 exemplo com números menores:
de 1 a 10

2+3+5+7=17

se eu fizer a raiz do número a soma não sera a mesma olha:
de 1 a 100(a raiz se 100 é 10)

2+3+5+7+11+13+17+19+23+29+31+37+41+43+47+53+59+61+67+71+73+79+83+89+97= 1060

Este método deve ser um pouco mais rápido:

public static boolean primos(long x){  
    if (x == 1){ // 1 é caso especial, e não é primo
        return false;
    }

    // sabemos que o 1 é divisor de todos os números, podemos começar a procurar no dois
    // basta percorrer a lista até x/2. O máximo divisor que um número tem, sem ser ele próprio é a sua metade.
    for(long i=2;i<=x/2;i++) { 
    
        if((x%i)==0) {
            return false; //Assim que encontra um divisor, sabe que o número não é primo.
        }
    }
    return true; //não encontrou divisores, o número é primo
 }  

Na verdade você já tem um algoritmo eficiente naquele outro tópico.

E só para corrigir o pmlm em questão da eficiência, quando estamos falando de números primos você pode começar pela raiz quadrada do número, não precisa ser da metade. O que torna o algoritmo realmente bastante eficiente.

O crivo de Eratóstenes funciona de forma eficiente para números primos menores que 10 milhões.

[quote=DavidUser]Não é o mesmo do outro tópico!
O problema é que aki eu não tenho que calcular os fatores primos mais tenho de somar todos os primos existentes de 1 a 2000000 exemplo com números menores:
de 1 a 10

2+3+5+7=17

se eu fizer a raiz do número a soma não sera a mesma olha:
de 1 a 100(a raiz se 100 é 10)

2+3+5+7+11+13+17+19+23+29+31+37+41+43+47+53+59+61+67+71+73+79+83+89+97= 1060[/quote]

O Bruno Bastos indicou o caminho correto: modifique o meu programa que acha os números primos, para poder calcular a soma.
Calcular essa soma de 1 até 2000000 vai levar cerca de 5 a 10 segundos, dependendo da velocidade do seu computador.
Não é necessário testar cada primo um por um; se fizer do jeito que você quer fazer, vai levar cerca de 10 a 15 horas, e isso não é legal.

[quote=BrunoBastos]Na verdade você já tem um algoritmo eficiente naquele outro tópico.

E só para corrigir o pmlm em questão da eficiência, quando estamos falando de números primos você pode começar pela raiz quadrada do número, não precisa ser da metade. O que torna o algoritmo realmente bastante eficiente.[/quote]

Dinovo!.. :x

se calulo os de 1 a 10: 2+3+5+7=17
ja os de 100 é bem diferente da muito mais intendeu! eu quero a soma de todos os primos entre eles.

De novo, vou mostrar o resultado pra você conferir se é isso mesmo.

A soma dos primos de 0 até 2.000.000 é 142.913.828.922 (use um long para fazer a totalização; esse número estoura um int).

Pela sua definição, 1 não é primo nem não-primo e não será considerado na somatória.

deu não!
usei o método de erastoteles e ficou em 999998000002

olha ai:

public class p10 {
    public BitSet bs;
    public static void main(String[]args){
        p10 s= new p10();
        int num=2000000;//num é o valor final
        long sum=0;

        s.findprimes((int)num+1);
        for(int i=2;i<=num-2;i++) if(s.isprime(i)==true)sum+=i;
        
        System.out.println(sum);
    }
    //pelo método de erastoteles:
    public void findprimes(int n){
        bs = new BitSet(n+1);
        int pz=(int)Math.sqrt(n);
        bs.set(0, n);
        int x=2;//primo inícial
        while (x<=2){
            for(int i=x+x;i<=n;i+=x)bs.clear(i);
            x=bs.nextSetBit(x+1);
        }
    }
    public boolean isprime(int n){
        return bs.get(n);
    }
}

Teste sua rotina para n = 10 e n = 100, para ver se dá 17 ou 1020, conforme você mesmo postou.

Dica: você não copiou direito meu programa. Veja o que você fez no “while”.

E de qualquer maneira o grego chato que inventou o tal método é Eratóstenes, não Erastoteles (ele não é um mestiço de Aristóteles e Eros).

tem algo errado?

minha rotina…

[code]public class NumerosPrimos {
public static boolean isPrimo(int numero) {
if (numero < 2)
return false;

    boolean result = true;
    int metade = numero / 2;
    for (int i = 2; i <= metade; i++) {
        if (numero % i == 0) {
            result = false; 
            break;  //putz tinha eskecido o break ... restartei agora ta + rapido
        }
    }
    return result;
}

public static void main(String ... args) {
    long soma = 0;
    for (int i = 0; i <= 2000000; i++)
        if (isPrimo(i)) {
            soma += i;
            System.out.println(i + ": " + soma);
        }
    System.out.println(soma);
    
}

}[/code]

foda q é lento para KCTs ahuahuahu…

no momento esta em 257353: 2770679587

o inicio deu isso

2: 2 3: 5 5: 10 7: 17 11: 28 13: 41 17: 58 19: 77 23: 100 29: 129 31: 160 37: 197 41: 238 43: 281 47: 328 53: 381 59: 440 61: 501 67: 568 71: 639 73: 712 79: 791 83: 874 89: 963 97: 1060 101: 1161

Ops! Saquei malz ae
troquei a raiz do numero por 2

Salve Eratosrenes em!
Mas fiquei sabendo de um método ainda mais rápido que utilizava o método de Eratostenes e de outro matemático acho que francês.

Sei q tem uma parte que se pega o resultado do numero dividido por 66.

passado o primeiro milhão… vamo em…

1.024.951: 39.406.066.834 1.024.957: 39.407.091.791 1.024.963: 39.408.116.754

Lavieri esse seu método é muito lento e exige muito da máquina! é melhor ficar com o do Grego chato.
Simples e útil!

uhuhuh acabou agora da forma tradicional ^^

1999957: 142907828981 1999969: 142909828950 1999979: 142911828929 1999993: 142913828922 142913828922