Return of prime numbers?

Asked

Viewed 175 times

-2

I’m having trouble with some returns stating that some prime numbers are not primes. What is the error in my code?

package capitulo4.laboratorio;
import java.util.Scanner;
public class Laboratorio1 {

    public static void main (String[] args) {
        
       int valor = 1;
       
        Scanner numero = new Scanner (System.in);
    
        System.out.print ("Informe o seu numero: ");
        valor = numero.nextInt();
        
    Boolean numeroPrimo = valor%2 !=0 && valor%3 !=0 && valor%5 != 0 && 
      valor%7 !=0 && valor%11 !=0 && valor%13 !=0 && valor%17 !=0 && 
      valor%19 !=0 && valor%23 !=0; 
    
        if (valor >= 1 && valor/valor==1 && numeroPrimo == true) {
            
        System.out.println("O número informado é primo!!!");
            } else {
                System.out.println("O número informado NAO é primo.");
            }
        numero.close();
    }
}

2 answers

1

Prime numbers are numbers larger than 1 (one) and are divisible only by the number 1 (one) and by itself, that is if in any case we obtain the rest division equal to zero from its predecessors it will not be prime, for example.

4 % 2 = 0 disqualified, so thinking you may have a condition where if the rest of the division of a number is zero it will not be prime.


class Primo {
    public static void main(String args[]) {
        int numero, contador, i;
        i = 2;
        contador = 0;
        numero = Integer.parseInt(JOptionPane.showInputDialog(" Digite o numero "));
        
        while (i < numero) {
            if (numero % i == 0) contador++;
            i++;
        }
        
        if (contador > 0 || numero == 1) JOptionPane.showMessageDialog(null, "nao é primo " + numero);
        else JOptionPane.showMessageDialog(null, "é primo " + numero);
    }
}

ie if the if (numeroVerificao % antecessores == 0) não é primo;

you need to make a repeat loop because if you’re not going to have to check each case by itself it might be tricky, I switched the Scanner class to Joptionpane just to make it cooler.

1

If search here on the site, will find various algorithms to check if a number is prime.


Your algorithm only checks if the number is divisible by some prime numbers, up to 23. That’s well limited, as it will not take several cases. For example, your code says that the number 961 is prime (but it is not, as it is divisible by 31).

Another weird thing is the condition valor / valor == 1 in the if - every non-zero integer divided by itself gives 1, so why test this?

There’s no reason to use the wrapper Boolean (with capital "B"), could have used the primitive boolean (with "b" tiny) no problem (read more on It is ideal to use primitive types in Java?).

Anyway, you can improve a little. Instead of testing the division by fixed values, just make a loop that will test whether the number is divisible by several other numbers. A naive implementation would be:

boolean numeroPrimo;
if (valor == 2) {
    numeroPrimo = true;
} else if (valor % 2 == 0) {  // se é par, mas não é 2, não é primo
    numeroPrimo = false;
} else {
    numeroPrimo = true;
    for (int i = 3; i < valor; i += 2) { // testo apenas se é divisível por ímpares
        if (valor % i == 0) {
            numeroPrimo = false;
            break; // já sei que não é primo, interrompe o for
        }
    }
}

if (numeroPrimo) {
    System.out.println("O número informado é primo!!!");
} else {
    System.out.println("O número informado NAO é primo.");
}

2 is the only even number that is prime, so I test this special case first. Then, if it is not 2, I test if it is even (because every even number is divisible by 2 and therefore not prime).

If the number is odd, I test if it is divisible by some odd number (I don’t need to test the division by even numbers, because if it were divisible by an even number, then it would also be even and would already have entered the else if (valor % 2 == 0)).

Also note that I don’t need to test if (numeroPrimo == true), is redundant and unnecessary. Boolean variables can be directly tested (only if (numeroPrimo)).


It can improve a little.

I have not tested if the number is less than or equal to 1, for example.

And I don’t need to do the loop until valor, I can go to the square root of the number, that is enough.

And with the exception of 2 and 3, all other prime numbers are in the form 6k - 1 or 6k + 1 (ie, are predecessors or successors of a multiple of 6), so I can make a loop that only tests these cases:

boolean numeroPrimo;
if (valor <= 1) {
    numeroPrimo = false;
} else if (valor == 2 || valor == 3) {
    numeroPrimo = true;
} else if (valor % 2 == 0 || valor % 3 == 0) {
    numeroPrimo = false;
} else {
    numeroPrimo = true;
    for (int i = 5; i < Math.sqrt(valor); i += 6) {
        if (valor % i == 0 || valor % (i + 2) == 0) {
            numeroPrimo = false;
            break; // já sei que não é primo, interrompe o for
        }
    }
}

The loop starts at 5 (the lowest positive number of the form 6k - 1), and then I test if valor is divisible by 5 and 7 (i.e., 6k - 1 or 6k + 1). Then the loop proceeds 6 by 6, as it tests only the numbers that are predecessors or successors of multiples of 6. The for proceeds to the square root of the valor.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.