I need to build a method that calculates prime numbers.
I'm testing it and it's giving me the wrong answers and I don't know how to solve it! For example, it returns true to 98262679 instead of false. Where is my mistake?
public static boolean itsPrime(int nbTest){ // Tests for prime numbers method
boolean prime = false;
if (nbTest <= 1){
return false;
} else if (nbTest == 2){ // Two is prime
return true;
} else if ((nbTest != 2) && (nbTest % 2 == 0)){ // Evens except number 2
return false; // are not prime
} else if (nbTest % 2 != 0){ // For all remaining odds
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2){
if (nbTest % i == 0){
prime = false;
} else {
prime = true;
}
}
}
return prime;
}
I'm learning Java and my professor asked us to construct the method itsPrime was based on this:
For the first subtask, write a function `itsPrime` that takes an `int`
as argument and returns a `boolean`, `true` if the argument integer is prime
and `false` otherwise.
To test whether an integer x is prime, one can proceed as follows:
all integers less than or equal to 1 are not prime;
2 is prime;
all other even integers are not prime;
for all remaining integers (obviously odd), search for a divisor:
loop from 3 to the square root of the integer x (The square root of x can
be computed as ‘‘Math.sqrt(x)'' in Java.); if the remainder of the integer
division of x by the loop index is zero, then x is not prime;
if all remainders were non-zero at the end of the loop, then x is prime;
I know the answer is there somewhere in all the answers above, but I think that each require an explanation.
Here's a summary of all the enhancements you could make to your code:
1) Don't declare a boolean to return, since you are already returning true or false throughout your code. Remove this line from your code (call it [1]):
boolean prime = false;
You'll see why after you've fixed the rest of your function. Comment it out if desired, for now.
2) In your second else if, let's call it [2], you have:
else if ((nbTest != 2) && (nbTest % 2 == 0)){
return false;
}
You already checked if nbTest is 2 in your first else if, so you don't need to check if it's not 2 again. If it entered the first if else, your function will return true. When a function returns, it is done. It returns the value to the caller and the rest of the code is not executed.
Thus, you may replace that second if else, [2], with:
else if (nbTest % 2 == 0) { // all other even integers are not prime
return false;
}
3) If you enter third else if, this means that the rest of the code above already executed, and it either returned, or the program continued.
You may replace that third else if (nbTest % 2 != 0){ for:
else {
4) This is the one error that you really have to make your function return the wrong answer (call this snippet [4]):
if (nbTest % i == 0){
prime = false;
If you find that the number you are testing is divisible (i.e. the remainder is zero), you are done. You definitely know that it is not prime.
You may replace this code, [4], with:
if(nbTest % counter == 0) {
return false;
}
Thus, returning false. It is not a number. And the function does not keep executing. Your error was continuing execution after the function finds out that your input is not prime.
Finally, you may leave your return true at the end of the function body. If the function never returned from the previous tests, or from the loop, it has to be a prime number. Remember that first line I told you to remove? The boolean declaration? Since you never return a value from a variable, you just return true or false, you don't need that [1] line.
As an extra, a good read on finding prime numbers, which you might want to share with your professor:
https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
You should stop once you here:
if (nbTest % i == 0){
return false;
}
Delete the prime variable (it is an unnecessary step, see below).
Change the for loop:
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2){
if (nbTest % i == 0){
prime = false;
} else {
prime = true;
}
}
To this:
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2)
if (nbTest % i == 0)
return false;
This simply breaks out of the function early if it isn't prime (if a factor has been found).
You shouldn't keep testing for primality once prime has been set to false for a number.
Replace:
if (nbTest % i == 0){
prime = false;
with:
if (nbTest % i == 0){
return false;
And the last test is useless, you can just keep a basic else:
else if (nbTest % 2 != 0){ => else {
Your for loop is not correct.
A prime number is a number which is divisible by 1 and itself only. So, if a number A is divisible by any other number except 1 and itself, then A is a nonprime.
Just replace your for loop with the one below
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2) {
if (nbTest % i == 0)
return false;
}
Once it is found that nbTest is divisible by some number, there is not point in continuing the loop. Return `nbTest is nonprime, then and there.
Related
Write a method named hasSharedDigit with two parameters of type int.
Numbers are between 10 and 99
The method should return true if there is a digit that appears in both numbers, such as 2 in 12 and 23; otherwise, the method should return false.
I have a solution, but don't quite understand how it works. I need an English explanation.
public class SharedDigit {
public static boolean hasSharedDigit(int numA,int numB){
if((numA<10||numA>99)||(numB<10||numB>99)){
return false;
}
int realNumB=numB;
while(numA>0){
int numADig=numA%10;
while(numB>0){
int numBDig=numB%10;
if(numADig==numBDig){
return true;
}
numB=numB/10;
}
numA=numA/10;
numB=realNumB;
}
return false;
}
}
I don't understand how this code is checking all possibilities of matching numbers
This here:
while(numA>0){
int numADig=numA%10;
uses the modulo operator to "get" the last digit of a number, see here for more information. So this first step gets you the "3" from 13 for example.
Later, you do:
numA=numA/10;
That turns 13 into 1 (int division)! That initial loop condition before ensures that you stop when you did 13 / 10 .. and then 1 / 10.
So this loops turns 13 into 3, then 1, and then stops.
And the same "method" is used to get the digits of the second number. And as soon as you find a digit in both numbers, you can return true.
Otherwise, if you walked trough all digits of the first number, and compared them against all digits in the second number ... no match, return false.
The real answer here, btw: when you do not understand what code does:
use a search engine to research all the things in the source you do not know
use a debugger, or simple System.out.printl() statements to enable yourself to observe what the code is doing
then finally, when all of that fails, and leaves you with doubts, then come here and ask for help
Have a look on my correct solution.
public class SharedDigit {
public static boolean hasSharedDigit (int one, int two) {
int modulusOne = one % 10;
int modulusTwo = two % 10;
int divisionOne = one / 10;
int divisionTwo = two / 10;
if ((one < 10 || one > 99) || (two < 10 || two > 99)) {
return false;
} else if (one == two){
return true;
} else if (modulusOne == modulusTwo){
return true;
} else if (divisionOne == divisionTwo){
return true;
} else if (divisionOne == modulusTwo){
return true;
} else if (divisionTwo == modulusOne){
return true;
} else {
return false;
}
}
}
Isn't this one way to test whether a number is a power of 2?
boolean isPowerOfTwo(int n) {
return (n%2==0);
}
Are you sure that you are checking power of 2? Rather, being checked divisible with 2. If you are serious, use the piece of cake snippet
return n > 0 && ((n & -n) == n);
The second way,
private static boolean powerOf2(int num)
{
if(num <= 0){
return false;
}
while(num > 1)
{
if(num % 2 != 0)
{
return false;
}
num = num / 2;
}
return true;
}
That function checks whether or not an integer is even (i.e divisible by 2), not whether or not the integer is a power of 2.
To check if a number is a power of 2, you should look at its bits. ints that are a power of 2 will have one bit set to 1 and all others set to 0.
boolean isPowerOf2(int i) {
return Integer.bitCount(i) == 1;
}
The % is the modulo operator, meaning the remainder after division. your method checks if the int n is divisible by 2
I don't understand this 'for' loop in Java
This loop is just to check if a number is prime or not. I understand the first statement because 1 is not a prime number but it's what happens in the 'for' statement. Why is 'primeNumber' being divided by two and why is the second 'if' calculating for a remainder of zero? how does this code help to confirm a prime number? what is it doing?
public static boolean isPrime (int primeNumber) {
if (primeNumber == 1) {
return false;
}
for (int primeDivider=2; primeDivider <= primeNumber/2; primeDivider++) {
if (primeNumber % primeDivider == 0) {
return false;
}
}
return true;
}
A prime number can only be divided by itself and one. 7 is prime because only 1 and 7 divide into 7. Also 8 is not prime because as well as 1 and 8, both 2 and 4 divide into 8.
Look at the for loop and see what values primeDivider takes: 2, 3, 4, 5, ... The loop tries each of these in turn to see if it divides into the number you are testing. If it divides evenly, with a remainder 0, then the number being tested is not prime and the method returns false. If none of the numbers divide, then the number being tested in prime and the method returns true. As an aside, primeNumber is a bad variable name. Something like possiblePrime would be better. The number being tested might not be prime.
The primeDivider sequence stops at half the number being tested. If a number is not prime (a composite number) then at least one of its divisors is guaranteed to be less than or equal to half the number.
As others have said, this is not a very efficient test. Here is a slightly more efficient version for you to study:
public static boolean isPrime (int possiblePrime) {
// Test negatives, zero and 1.
if (possiblePrime <= 1) {
return false;
}
// Test even numbers
if (possiblePrime % 2 == 0) {
// 2 is the only even prime.
return possiblePrime == 2;
}
// Test odd numbers >= 3.
int limit = possiblePrime / 2;
for (int primeDivider = 3; primeDivider <= limit; primeDivider += 2) {
if (possiblePrime % primeDivider == 0) {
return false;
}
}
// Only prime numbers reach this point.
return true;
}
By treating odd and even numbers separately, you can catch all the even numbers with a single test and by stepping primeDivider by 2 each time, roughly halve the time taken for odd numbers.
As billjamesdev says, that can be made even more efficient by using:
int limit = (int)Math.floor( Math.sqrt( possiblePrime ));
A composite number will always have a divisor, other than 1, less than or equal to its square root.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
So I just started some java and I'm trying to get the user to enter a number and test whether it is prime or not. This is the loop I have for the program.
do{
for(testNumber = 2; testNumber < numb; testNumber++){
if(numb % testNumber == 0){
test = false;
}else{
test = true;
}
}
if(test = true){
System.out.println("The number is prime.");
}else{
System.out.println("The number is not prime.");
}
System.out.println("Enter a number. Enter 0 to exit.");
numb = number.nextInt();
}while(numb != 0);
Every number that is entered becomes out to be true! To me the logic seems to be correct.
if(test = true){
should be
if(test == true){
The first one being an "assignment" operator and the second one being a logical (equality test) operator. Read more on the official documentation.
Note
I am not commenting on other parts of your code as a learning exercise for you. Your code can be optimized and improved! You're on the right track. Keep it up!
First, your are using the assignment operator = to compare test to true, which results in test always being true. It's already a boolean, just use it without the extraneous comparison:
if(test){
Second, you are overwriting the value of test in each for loop iteration. Initialize it to true, and only set it to false if you find a factor.
test = true;
for(testNumber = 2; testNumber < numb; testNumber++){
if(numb % testNumber == 0){
test = false;
}
}
Additionally, you don't need to test testNumbers past the square root of the number numb.
int limit = (int) Math.sqrt(numb);
for(testNumber = 2; testNumber <= limit; testNumber++){
You have two problems. First, think about your loop logic: You're actively setting the test variable on every pass through the loop. Since the loop ends at numb - 1, it's nearly always going to set test to true on the last pass. Instead, set test to true before the loop and only set it to false if you find a factor: That will leave it false as soon as you detect it's not prime. (Putting that loop inside a separate method so you can return immediately would be even better.)
isPrime = true;
for(int factor = 2; factor < numb; factor++) { // see below for advice on condition
if(numb % factor == 0)
isPrime = false;
}
Second, you're setting test in your if statement. You must use == to check for equality, and in Java, it's more idiomatic to just use if(test).
As a matter of style, a variable named test is not very descriptive. I suggest the isPrime name I used above.
Finally, you only need to check up to the square root of testNumber, but don't use a floating-point operation and then truncate the result, or you might miss an exact square-root factor.
You should break if you found it and if condition == true
do{
for(testNumber = 2; testNumber < numb; testNumber++){
if(numb % testNumber == 0){
test = false;
break;
}else{
test = true;
}
}
if(test == true){
System.out.println("The number is prime.");
}else{
System.out.println("The number is not prime.");
}
System.out.println("Enter a number. Enter 0 to exit.");
numb = number.nextInt();
}while(numb != 0);
Write a method named hasAnOddDigit that returns whether any digit of a positive integer is odd. Your method should return true if the number has at least one odd digit and false if none of its digits are odd. 0, 2, 4, 6, and 8 are even digits, and 1, 3, 5, 7, 9 are odd digits.
For example, here are some calls to your method and their expected results:
Call Value Returned
hasAnOddDigit(4822116) true
hasAnOddDigit(2448) false
hasAnOddDigit(-7004) true
You should not use a String to solve this problem.
This is my attempt at the question:
public boolean hasAnOddDigit(int num){
int number=0;
while (number > 0) {
number= number % 10;
number = number / 10;
}
if(number%2==0 && num%2==0){
return false;
}else{
return true;
}
}
Called for hasAnOddDigit(4822116) and it gives me a false instead of true.
Your method should check each digit as it goes through the loop, rather than waiting for the loop to complete before making its decision. Currently, the while loop runs the number down to zero, and only then tries to check the value. Naturally, by the time the loop is over, both values are zero, so the return is false.
public boolean hasAnOddDigit(int num){
// You do not need to make a copy of num, because
// of pass-by-value semantic: since num is a copy,
// you can change it inside the method as you see fit.
while (num > 0) {
int digit = num % 10;
if (digit % 2 == 1) return true;
num /= 10;
}
// If we made it through the loop without hitting an odd digit,
// all digits must be even
return false;
}
A recursive version which might be more intuitive for some.
private boolean hasAnOddDigit(int num) {
if (num<10) {
return num%2==0 ? false : true;
} else {
return check(num%10) || check (num/10);
}
}