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
.