I have this code here that asks a user to enter a number then calls the isPrime method to calculate if the number is prime or not. It then prints out to the screen the result. I did a lot of trial and error to get this code to work, but I don't really understand all the way why this program works. For instance if I enter 9, the code would give me back a remainder, which should return true, which should make 9 a prime number, but it's not and the program works, saying that 9 is not a prime number. Just wondering why it works.
package homework_chap5;
import java.util.Scanner;
public class Homework_Chap5 {
//Pg 313 #7
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter number: ");
int num = s.nextInt();
if(isPrime(num)) {
System.out.println("Number is prime");
} else {
System.out.println("Number is not prime");
}
}
public static boolean isPrime(int num)
{
for(int i = 2; i <= num/2; i++)
{
if (num%i==0)
{
return false;
}
}
return true;
}
}
For instance if I enter 9, the code would give me back a remainder, which should return true
No, for num==9 and i==2, num%i==0 will be false, but the loop will proceed to check for i==3 whether num%i==0. This time the condition will be true and the isPrime method with return false.
Only after the loop ends, at which point we know that num is not divisible by any of the values of i tested, the method will conclude that num is a prime number and return true.
By definition, a number is prime if it is divisible by only 1 and itself. Also rather than checking divisibility of the number num by all the numbers between 1 and num, it is sufficient to check for divisibility by numbers between 1 and num/2 because no number greater than the mid value of the number num perfectly divides the number. So go from 2 till num/2 and see if any number divides the number num i.e. num % i == 0 where i in range [2, num/2]. If any such i exists then the number is not prime. If for no i in the range [2, num/2] num%i == 0 then num is prime.
However, the code can be optimized by checking for divisibility of num by all the numbers in range [2, sqrt(num)]instead of [2,num/2]. You can check the efficiency for your self.
Related
Should receive an output of the largest/smallest numbers within the inputs, what seems to be the problem? I have tried looking it up online, the source code appears to be the same. Thank you for your assistance.
Source code:
package counting.largest.smallest;
import java.util.Scanner;
public class CountingLargestSmallest {
public static void main(String[] args) {
Scanner TheN = new Scanner(System.in);
int counter = 0;
int number;
int smallest = Integer.MIN_VALUE;
int largest = Integer.MAX_VALUE;
while (counter < 10) {
System.out.print("Integer=");
number = TheN.nextInt();
counter++;
if (number < smallest) {
number = smallest;
} else if (number > largest) {
number = largest;
}
}
System.out.println("\nSmallest=" + smallest);
System.out.println("Largest=" + largest);
}
}
Output:
Integer=1
Integer=2
Integer=3
Integer=4
Integer=5
Integer=6
Integer=7
Integer=8
Integer=9
Integer=10
Smallest=-2147483648
Largest=2147483647
there were 3 bugs:
1.
int smallest=Integer.MIN_VALUE;
int largest=Integer.MAX_VALUE;
number=smallest;
number=largest;
Using else if
1: When you want to find a min number keep it Integer.MAX_VALUE and when you want to find max keep it has Integer.MIN_VALUE.
Why for min we Initialize Integer.MAX_VALUE and for max we Initialize Integer.MIN_VALUE?
Say you want to multiple n numbers from the user. So we will declare and initialize mul variable to 1. cause we know any number multiple by 1 will give us the same number.
Whereas if we initialize mul with 0 it will give us 0 only.
So we say 1 for multiplication is identity.
Similarly, for finding Minimum number we use an identity that is Integer.MAX_VALUE.
So that number that less then Integer.MAX_VALUE are saved in Samllest variable.
int smallest=Integer.MAX_VALUE;
Similarly for max we initialize it with Integer.MIN_VALUE SO that number that are greater then Integer.MIN_VALUE are stored in largest variable.
int largest=Integer.MIN_VALUE;
2: You are assigning number variable the value of smallest and largest it should be like smallest=number and largest=number
when you write x=0 it says x is 0 that means x is changed, Similarly when you write number=smallest its number = Integer.MAX_VALUE and smallest is not changing at all.
So you should write like smallest = number, It means smallest is the number and smallest is changing every time condition satisfies.
3: When you write
if(condition){
}else if(conditon){
}
else if is only excuted when first if statement if false and if first condition is true second if is never executed.
if we have descending number then second if will never be excuted which would result in having Integer.MIN_VALUE in largest variable.
And here you want to check for both min and max so we should have indepent if statement for each
if(condition){
}
if(condition){
}
Code:
Scanner TheN= new Scanner(System.in);
int counter=0;
int number;
// changed
int smallest=Integer.MAX_VALUE;
int largest=Integer.MIN_VALUE;
while(counter<10){
System.out.print("Integer=");
number=TheN.nextInt();
counter++;
if(number<smallest){
// changed
smallest= number;
}
if(number>largest){
// changed
largest=number;
}
}
System.out.println("\nSmallest="+smallest);
System.out.println("Largest="+largest);
Output:
Integer=1
Integer=2
Integer=2
Integer=4
Integer=3
Integer=6
Integer=7
Integer=8
Integer=9
Integer=10
Smallest=1
Largest=10
I'm having some trouble getting my head around this program that's used an example in a guide book. It might be more of a math question than a coding question. Edited to include code!
// Find prime numbers between 2 and 100.
class Prime {
public static void main(String args[]) {
int x, y;
boolean isprime;
for(x=2; x < 100; x++) {
isprime = true;
for(y=2; y <= x/y; y++)
if((x%y) == 0) isprime = false;
if(isprime)
System.out.println(x + " is a prime number.");
}
}
}
Here's my understanding of the program:
Declare x (potential prime number) and y (a number to divide x by - if there is a division possible [other than by itself or 1] that yields no remainder, it's not a prime).
Declare a boolean value to hold whether the number is prime.
Create a for loop to test each and every number between 2 and 100
Default isprime boolean to true
Create a for loop to divide the prime by numbers between 2 and ??? (I don't understand the condition part of this for loop)
I tried to put in a system.out.print option here to show what x and y were at each iteration, but it then calculated non-prime numbers as prime numbers.
If you divide the prime by all these numbers and there is a number without a remainder, change boolean isprime to false.
If, after going through all values and all of them had a remainder, print that this is a prime number.
Its skipping numbers that do not make sense to check to see if they are factors. For example, if x = 49, it will check till y = 7 after which the condition will be false. Since it has already checked for all the numbers before 7, a higher factor is not possible that the square root of the number. So essentially, it checks for factors from 2 to square root of the number.
Okay my issue is less of how to figure out if a number is prime, because I think I figured that out, but more of how to get it to display properly.
Here's my code:
public static void main(String[] args) {
// Declare Variables
int randomNumbers = 0;
int sum = 0;
//Loop for number generation and print out numbers
System.out.print("The five random numbers are: ");
for (int i = 0; i <= 4; i++)
{
randomNumbers = (int)(Math.random()*20);
sum += randomNumbers;
if (i == 4) {
System.out.println("and " + randomNumbers + ".");
}
else {
System.out.print(randomNumbers + ", ");
}
}
//Display Sum
System.out.println("\nThe sum of these five numbers is " + sum + ".\n");
//Determine if the sum is prime and display results
for(int p = 2; p < sum; p++) {
if(sum % p == 0)
System.out.println("The sum is not a prime number.");
else
System.out.println("The sum is a prime number.");
break;
}
}
}
Now my problem is, if the number ends up being something like 9, it'll say it is a prime number, which it is not. I think the issue is that the break is stopping it after one loop so it's not incrementing variable p so it's only testing dividing by 2 (I think). But if I remove the break point it will print out "The sum is/is not a prime number" on every pass until it exits the loop. Not sure what to do here.
Your method for finding if your number is prime is the correct method.
To make it so that it does not consistently print out whether or not the number is prime, you could have an external variable, which represents whether or not the number is prime.
Such as
boolean prime = true;
for (int p = 2; p < sum; p++) {
if (sum % p == 0) {
prime = false;
break;
}
}
if (prime)
System.out.println("The sum is a prime number.");
else
System.out.println("The sum is not a prime number.");
By doing this method the program will assume the number is prime until it proves that wrong. So when it finds it is not prime it sets the variable to false and breaks out of the loop.
Then after the loop finishes you just have to print whether or not the number was prime.
A way that you could make this loop faster is to go from when p = 2 to when p = the square root of sum. So using this method your for loop will look like this:
double sq = Math.sqrt((double)sum);
for (int p = 2; p < sq; p++) {
//Rest of code goes here
}
Hope this helps
You need to store whether or not the number is prime in a boolean outside of the loop:
//Determine if the sum is prime and display results
boolean isPrime = true;
for(int p = 2; p < sum; p++) {
if(sum % p == 0){
isPrime = false;
break;
}
}
if(isPrime){
System.out.println("The sum is a prime number.");
} else {
System.out.println("The sum is not a prime number.");
}
You are right, currently your code tests dividing by two, and the break command is stopping after one loop.
After the first go of your loop (p==2), the break will always stop the loop.
The fastest fix to your code will change the loop part like this:
boolean isPrime=true;
for(int p = 2; p < sum; p++) {
if(sum % p == 0) {
isPrime=false;
System.out.println("The sum is not a prime number.");
break;
}
}
if (isPrime)
System.out.println("The sum is a prime number.");
This code can be improved for efficiency and for code elegance.
For efficiency, you don't need to check divisibility by all numbers smaller than sum, it's enough to check all numbers smaller by square-root of sum.
For better code, create a seperate function to test if a number is prime.
Here is an example that implements both.
// tests if n is prime
public static boolean isPrime(int n) {
if (n<2) return false;
for(int p = 2; p < Math.sqrt(n); p++) {
if(n % p == 0) return false; // enough to find one devisor to show n is not a prime
}
return true; // no factors smaller than sqrt(n) were found
}
public static void main(String []args){
...
System.out.println("sum is "+ sum);
if (isPrime(sum))
System.out.println("The sum is a prime number.");
else
System.out.println("The sum is not a prime number.");
}
Small prime numbers
Use Apache Commons Math primality test, method is related to prime numbers in the range of int. You can find source code on GitHub.
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
// org.apache.commons.math3.primes.Primes
Primes.isPrime(2147483629);
It uses the Miller-Rabin probabilistic test in such a way that a
result is guaranteed: it uses the firsts prime numbers as successive
base (see Handbook of applied cryptography by Menezes, table 4.1 / page 140).
Big prime numbers
If you are looking for primes larger than Integer.MAX_VALUE:
Use BigInteger#isProbablePrime(int certainty) to pre-verify the prime candidate
Returns true if this BigInteger is probably prime, false if it's
definitely composite. If certainty is ≤ 0, true is returned.
Parameters: certainty - a measure of the uncertainty that the caller
is willing to tolerate: if the call returns true the probability that
this BigInteger is prime exceeds (1 - 1/2certainty). The execution
time of this method is proportional to the value of this parameter.
Next use "AKS Primality Test" to check whether the candidate is indeed prime.
So many answers have been posted so far which are correct but none of them is optimized. That's why I thought to share the optimized code to determine prime number here with you. Please have a look at below code snippet...
private static boolean isPrime(int iNum) {
boolean bResult = true;
if (iNum <= 1 || iNum != 2 && iNum % 2 == 0) {
bResult = false;
} else {
int iSqrt = (int) Math.sqrt(iNum);
for (int i = 3; i < iSqrt; i += 2) {
if (iNum % i == 0) {
bResult = false;
break;
}
}
}
return bResult;
}
Benefits of above code-:
It'll work for negative numbers and 0 & 1 as well.
It'll run the for loop only for odd numbers.
It'll increment the for loop variable by 2 rather than 1.
It'll iterate the for loop only upto square root of number rather than upto number.
Explanation-:
I have mentioned the four points above which I'll explain one by one. Code must be appropriately written for the invalid inputs rather the only for valid input. Whatever answers have been written so far are restricted to valid range of input in which number iNum >=2.
We should be aware that only odd numbers can be prime, Note-: 2 is the only one even prime. So we must not run for loop for even numbers.
We must not run for loop for even values of it's variable i as we know that only even numbers can be devided by even number. I have already mentioned in the above point that only odd numbers can be prime except 2 as even. So no need to run code inside for loop for even values of variable i in for.
We should iterate for loop only upto square root of number rather than upto number. Few of the answers has implemented this point but still I thought to mention it here.
With most efficient time Complexity ie O(sqrt(n)) :
public static boolean isPrime(int num) {
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
you can use the Java BigInteger class' isProbablePrime method to determine and print whether the sum is prime or not prime in an easy way.
BigInteger number = new BigInteger(sum);
if(number.isProbablePrime(1)){
System.out.println("prime");
}
else{
System.out.println("not prime");
}
You can read more about this method here https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#isProbablePrime%28int%29
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.
//Getting Prime numbers from 2 to given range.
//When Inner for loop is running for number 2, it is printing 9 as a prime number.
import java.util.*;
import java.io.*;
class A
{
public static void main(String args[])
{
System.out.println("Enter the number till which the prime number is to be printed:");
Scanner sc = new Scanner(System.in);
int limit = sc.nextInt();
System.out.println("Printing the prime numbers from 1 to "+limit);
for(int num =2; num<=limit; num++)
{
for(int d=2; d<=num; d++)
{
if(num%d == 0)
{
break;
}
if()
{
System.out.println(num);
break;
}
}
}
}
}
Above the second loop keep a flag as true which means initially the number is a prime number.
boolean flag = true;
Second loop condition shall be d <= num/2
Inside the second loop to break if its not prime, or divisible by a number.
if(num%d == 0)
{
flag = false;
break;
}
Outside the second loop, print it if the flag is still true:
if(flag){
System.out.println(num);
}
Remember: For large scale prime number checking or generation, the algorithm of Sieve is always best.
I have a bad news. This program finds not the prime number but the odd numbers: 3, 5, 7, 9 etc.
You are printing the values if it is not divisible.
all the non prime numbers from 2 to 8 are divisible by 2 and hence it is showing only prime numbers.
in case when number is 9, it is printing 9 because 9%2 is not 0.