Reputation: 51
I am struggling to understand why code wouldn't work. According to the truth table/logic gates for AND and OR https://en.wikipedia.org/wiki/Truth_table I would assume that I would be able to have an if statement inside the for
-loop such that (p < 2 || p % i == 0)
would work for finding prime numbers but it fails when considering negative numbers.
I know that if you if take out the p < 2
and write it as an if statement outside this for
-loop it works, but if the p < 2
is inside the for
-loop it does not work. Why is this so?
public class test {
public static void main(String [] args) {
System.out.println("Hello World!");
int a = 7;
System.out.println("A is Prime: " + isPrime(a));
System.out.println();
int b = 4;
System.out.println("B is Prime: " + isPrime(b));
System.out.println();
int c = -7;
System.out.println("C is Prime: " + isPrime(c));
System.out.println();
int d = 53;
System.out.println("D is Prime: " + isPrime(d));
}
public static boolean isPrime(int p) {
for (int i = 2; i < p; i++) {
if (p < 2 || p % i == 0) {
return false;
}
}
return true;
}
}
Upvotes: 0
Views: 83
Reputation: 114300
You may want to invest in Math.abs(int)
:
public static boolean isPrime(int p) {
p = Math.abs(p);
for (int i = 2; i < p; i++) {
...
This will ensure that p
is always non-negative, and your initial assumptions about how the loop should behave are justified.
Upvotes: 1
Reputation: 476594
Because for p < 2
, the body of the for
loop is never performed. Indeed:
for (int i = 2; i < p; i++) {
// ...
}
If p = 2
, then it initializes i = 2
, and then checks i < p
which fails, and hence the body is never executed. It skips the for
loop, and thus returns true
.
We can fix it by performing a check before (or after) the for
loop, and even boost the performance of the loop slighly:
public static boolean isPrime(int p) {
if(p <= 2) {
return p == 2;
}
if(p % 2 == 0) {
return false;
}
for (int i = 3; i*i <= p; i += 2) {
if (p % i == 0) {
return false;
}
}
return true;
}
We can simply return false
first for all values less than 2
, and true
for 2. Furthermore we only need to iterate up to √p, since if there is a value j larger than √p that divides p, then there is a smaller value i = p/j that is smaller than √p that will already be checked. We furthermore only need to check odd numbers, since even numbers are already implied by the division by 2
.
Upvotes: 6