This question already has answers here:
How to check if a number is a power of 2
(32 answers)
Closed 7 years ago.
public class test{
public static void main(String[] args) {
int a=536870912;
System.out.print((Math.log(a)/Math.log(2)));
}
}
536870912 is a number that is power of two, but the result is 29.000000000000004, could anybody explain this? Thanks.
If n is a power of 2, then its binary representation will start with 1 and will contain only 0s after it.
So, you can do:
String binary = Integer.toBinaryString(a);
Pattern powerOfTwoPattern = Pattern.compile("10*");
System.out.println(powerOfTwoPattern.matcher(binary).matches());
Anyway, if you number is not really huge (i.e. fits the int or long range), then you can follow the suggestions here
You can use below method:-
boolean isPowerOfTwo (int x)
{
while (((x % 2) == 0) && x > 1) /* While x is even and > 1 */
x /= 2;
return (x == 1);
}
Explanation:- Repeatedly divides x by 2. It divides until either the quotient becomes 1, in which case x is a power of two, or the quotient becomes odd before reaching 1, in which case x is not a power of two.
pseudo-code following, easily adapted to java
boolean is_power_of_two(int num)
{
int i = Math.ceil(Math.log(num)/Math.log(2.0));
/*while ( i >= 0 )
{
// note 1 is taken as power of 2, i.e 2 ^ 0
// chnage i > 0 above to avoid this
if ( num == (1 << i) ) return true;
i--;
}
return false;*/
// or even this, since i is initialised in maximum power of two that num can have
return (num == (1 << i)) || (num == (1 << (i-1)));
}
NOTE it also can be done with discrete logarithm in constant-time without compiling to string represenation etc, but needs a precomputed table of discrete logarithms for base 2 or even using binary manipulation as in https://stackoverflow.com/a/600306/3591273, these approaches are constant-time but use the default representation of machine int or long
Related
I am working on a Java problem in which I need to check if the second-leading digit of an int (ex: the '2' in 123, or the '8' in 58347) of any size is a particular digit (such as a '2' or a '5'), and then assign true to a Boolean, if it is that digit. I am trying to do the modulo/divisor method, but I am not able to extract the second-leading digit if the number is large.
I searched Stack Overflow, and found a very similar question. However, the solution for that question works if the number is hard-coded as being two digits. I know there is a way by converting int to String, and I tried that method successfully, but I need to use int/modulo/division method. I tried doing (n%100)/10; but it got me second-to-last digit (ex: the '7' in 4562374), not second-after-first digit.
// n is a number such as 123, or 25, or 52856.
while (n > 0) {
int i=((n%10)/10);
if( (i==2)||(i==3) || (i==5)|| (i==7) )
{ secondDigit=true; }
else { secondDigit= false; } }
System.out.println(secondDigit);
Just keep dividing by 10 until the number is < 100 then do modulo 10, example:
class Main {
public static void main(String[] args) {
int n = 58347;
while (n >= 100) {
n /= 10;
}
System.out.println(n % 10); // prints 8
}
}
Not certain about the efficiency of this method, however its easy to read.
Integer.parseInt(String.valueOf(Math.abs(initial_value)).charAt(1)+"")
However, you have to ensure that the number has more than 1 digit.
Instead of repeatedly dividing the number you have until it's small enough for you to handle, how about finding out how big the number is so you only need to do a single division?
What I mean is that you should consider using logarithms to find out the magnitude of your number. Finding the base 10 logarithm of your number gets you its magnitude. For 100 the log_10 is 2, so you can do the following:
long magnitude = Math.log10(number);
long divisor = Math.pow(10, magnitude - 1);
long smallNumber = number / divisor;
int digit = smallNumber % 10;
Assignment:
Write a recursive function recPow that computes 2n for n >= 0 in Java. The function will have the following profile:
public static int recPow(int n)
The function must consider all cases and be tested exhaustively.
My Problem
I don't understand why my code returns -2147483648 when I enter recPow(31) instead of 2147483648. I know some of you might tell me to switch to long instead of int, but I believe due to the assignment's verbiage I need to stick with int. I have never been very good computing numbers if any one can help me understand why this happens I would truly, greatly appreciate it.
Additionally - larger exponents return 0 (however I think this may have to do with the fact that we need to use ints vs longs.)
My Code
public static int baseNum = 2, powResult = 1;
public static int recPow(int n) {
//if the int is not bigger than 0
//must only accept ints
if (n < 0) {
throw new IllegalArgumentException("n has to be > 0");
} else {
//recursion here
//base number = 2
if (n==0) {
return powResult;
} else {
powResult = powResult * baseNum;
return recPow(n - 1);
}
}
}
This is due to overflow of the int data type.
Java's int size is 32 bits, so the range is -2,147,483,648 to 2,147,483,647.
2^31 = 2147483648
So it is overflowing to -2147483648
as the binary value of 2,147,483,647 is 01111111111111111111111111111111 (one zero and 31 ones), where the first bit is the "sign bit" (2's complement form).
If you try to go beyond this limit (2,147,483,647) by 1 (i.e. adding 1 to it), it changes the sign bit to 1, making this int negative.
So it will become 10000000000000000000000000000000 (1 one and 31 zeros), giving you the answer -2147483648.
larger exponents return 0 (however I think this may have to do with the fact that we need to use ints vs longs.)
Correct.
int i = (int) 2147483648L; // -2147483648 due to over flow
int j = i * 2; // 0 due to overflow.
You can use long however this has the same problem but for a higher value.
public static long recPower(int baseNum, int power) {
if (power < 0) throw new IllegalArgumentException();
return power == 0 ? 1L : baseNum * recPower(baseNum, power - 1);
}
One way to check for an overflow is to see
public static long recPower(int baseNum, int power) {
if (power < 0) throw new IllegalArgumentException();
return power == 0 ? 1L : baseNum * recPower(baseNum, power - 1);
}
or to check for overflow
public static long recPower(int baseNum, int power) {
if (power < 0) throw new IllegalArgumentException();
return power == 0 ? 1L
: Math.multiplyExact(baseNum, recPower(baseNum, power - 1));
}
You can use BigInteger which has a much, much greater limit.
How do I check if a Java integer is a multiple of another number? For example, if int j is a multiple of 4.
Use the remainder operator (also known as the modulo operator) which returns the remainder of the division and check if it is zero:
if (j % 4 == 0) {
// j is an exact multiple of 4
}
If I understand correctly, you can use the module operator for this. For example, in Java (and a lot of other languages), you could do:
//j is a multiple of four if
j % 4 == 0
The module operator performs division and gives you the remainder.
Use modulo
whenever a number x is a multiple of some number y, then always x % y equal to 0, which can be used as a check. So use
if (j % 4 == 0)
//More Efficiently
public class Multiples {
public static void main(String[]args) {
int j = 5;
System.out.println(j % 4 == 0);
}
}
I am trying to write a simple program that takes a non-prime number and returns the first factor of it. I have to use a method to do this. I think that I am really close to the correct code, but I keep running into variable definition issues in my method. Here is my (currently incorrect) code:
public class testing {
public static void main(String[] args) {
int a;
a = 42;
System.out.println(factor(a));
}
//This method finds a factor of the non-prime number
public static int factor(int m) {
for(int y=2 ; y <= m/2 ; y++) {
if(m%y==0) {
return y;
continue;
}
}
return y;
}
}
Please let me know what's incorrect!
Regarding your code:
public static int factor(int m) {
for(int y=2 ; y <= m/2 ; y++) {
if(m%y==0) {
return y;
continue;
}
}
return y;
}
At the point of that final return y, y does not exist. Its scope is limited to the inside of the for statement since that is where you create it. That's why you're getting undefined variables.
In any case, returning y when you can't find a factor is exactly the wrong thing to do since, if you pass in (for example) 47, it will give you back 24 (47 / 2 + 1) despite the fact it's not a factor.
There's also little point in attempting to continue the loop after you return :-) And, for efficiency, you only need to go up to the square root of m rather than half of it.
Hence I'd be looking at this for a starting point:
public static int factor (int num) {
for (int tst = 2 ; tst * tst <= num ; tst++)
if (num % tst == 0)
return tst;
return num;
}
This has the advantage of working with prime numbers as well since the first factor of a prime is the prime itself. And, if you foolishly pass in a negative number (or something less than two, you'll also get back the number you passed in. You may want to add some extra checks to the code if you want different behaviour.
And you can make it even faster, with something like:
public static int factor (int num) {
if (num % 2 == 0) return 2;
for (int tst = 3 ; tst * tst <= num ; tst += 2)
if (num % tst == 0)
return tst;
return num;
}
This runs a check against 2 up front then simply uses the odd numbers for remainder checking. Because you've already checked 2 you know it cannot be a multiple of any even number so you can roughly double the speed by only checking odd numbers.
If you want to make it even faster (potentially, though you should check it and keep in mind the code may be harder to understand), you can use a clever scheme pointed out by Will in a comment.
If you think about the odd numbers used by my loop above with some annotation, you can see that you periodically get a multiple of three:
5
7
9 = 3 x 3
11
13
15 = 3 x 5
17
19
21 = 3 x 7
23
25
27 = 3 x 9
That's mathematically evident when you realise that each annotated number is six (3 x 2) more than the previous annotated number.
Hence, if you start at five and alternately add two and four, you will skip the multiples of three as well as those of two:
5, +2=7, +4=11, +2=13, +4=17, +2=19, +4=23, ...
That can be done with the following code:
public static long factor (long num) {
if (num % 2 == 0) return 2;
if (num % 3 == 0) return 3;
for (int tst = 5, add = 2 ; tst * tst <= num ; tst += add, add = 6 - add)
if (num % tst == 0)
return tst;
return num;
}
You have to add testing against 3 up front since it violates the 2, 4, 2 rule (the sequence 3, 5, 7 has two consecutive gaps of two) but that may be a small price to pay for getting roughly another 25% reduction from the original search space (over and above the 50% already achieved by skipping all even numbers).
Setting add to 2 and then updating it with add = 6 - add is a way to have it alternate between 2 and 4:
6 - 2 -> 4
6 - 4 -> 2
As I said, this may increase the speed, especially in an environment where modulus is more expensive than simple subtraction, but you would want to actually benchmark it to be certain. I just provide it as another possible optimisation.
This is what you probably want to do:
public static void main(String[] args) {
int a;
a = 42;
System.out.println(factor(a));
}
public static int factor(int m) {
int y = 0;
for (y = 2; y <= m / 2; y++) {
if (m % y == 0) {
return y;
}
}
return y;
}
And the output will be 2.
we need just a simple for loop like,
public static void finfFactor(int z) {
for(int x=1; x <= z; x++) {
if(z % x == 0) {
System.out.println(x);
}
}
I am working on a prime factorization program implemented in Java.
The goal is to find the largest prime factor of 600851475143 (Project Euler problem 3).
I think I have most of it done, but I am getting a few errors.
Also my logic seems to be off, in particular the method that I have set up for checking to see if a number is prime.
public class PrimeFactor {
public static void main(String[] args) {
int count = 0;
for (int i = 0; i < Math.sqrt(600851475143L); i++) {
if (Prime(i) && i % Math.sqrt(600851475143L) == 0) {
count = i;
System.out.println(count);
}
}
}
public static boolean Prime(int n) {
boolean isPrime = false;
// A number is prime iff it is divisible by 1 and itself only
if (n % n == 0 && n % 1 == 0) {
isPrime = true;
}
return isPrime;
}
}
Edit
public class PrimeFactor {
public static void main(String[] args) {
for (int i = 2; i <= 600851475143L; i++) {
if (isPrime(i) == true) {
System.out.println(i);
}
}
}
public static boolean isPrime(int number) {
if (number == 1) return false;
if (number == 2) return true;
if (number % 2 == 0) return false;
for (int i = 3; i <= number; i++) {
if (number % i == 0) return false;
}
return true;
}
}
Why make it so complicated? You don't need do anything like isPrime(). Divide it's least divisor(prime) and do the loop from this prime. Here is my simple code :
public class PrimeFactor {
public static int largestPrimeFactor(long number) {
int i;
for (i = 2; i <= number; i++) {
if (number % i == 0) {
number /= i;
i--;
}
}
return i;
}
/**
* #param args
*/
public static void main(String[] args) {
System.out.println(largestPrimeFactor(13195));
System.out.println(largestPrimeFactor(600851475143L));
}
}
edit: I hope this doesn't sound incredibly condescending as an answer. I just really wanted to illustrate that from the computer's point of view, you have to check all possible numbers that could be factors of X to make sure it's prime. Computers don't know that it's composite just by looking at it, so you have to iterate
Example: Is X a prime number?
For the case where X = 67:
How do you check this?
I divide it by 2... it has a remainder of 1 (this also tells us that 67 is an odd number)
I divide it by 3... it has a remainder of 1
I divide it by 4... it has a remainder of 3
I divide it by 5... it has a remainder of 2
I divide it by 6... it has a remainder of 1
In fact, you will only get a remainder of 0 if the number is not prime.
Do you have to check every single number less than X to make sure it's prime? Nope. Not anymore, thanks to math (!)
Let's look at a smaller number, like 16.
16 is not prime.
why? because
2*8 = 16
4*4 = 16
So 16 is divisible evenly by more than just 1 and itself. (Although "1" is technically not a prime number, but that's technicalities, and I digress)
So we divide 16 by 1... of course this works, this works for every number
Divide 16 by 2... we get a remainder of 0 (8*2)
Divide 16 by 3... we get a remainder of 1
Divide 16 by 4... we get a remainder of 0 (4*4)
Divide 16 by 5... we get a remainder of 1
Divide 16 by 6... we get a remainder of 4
Divide 16 by 7... we get a remainder of 2
Divide 16 by 8... we get a remainder of 0 (8*2)
We really only need one remainder of 0 to tell us it's composite (the opposite of "prime" is "composite").
Checking if 16 is divisible by 2 is the same thing as checking if it's divisible by 8, because 2 and 8 multiply to give you 16.
We only need to check a portion of the spectrum (from 2 up to the square-root of X) because the largest number that we can multiply is sqrt(X), otherwise we are using the smaller numbers to get redundant answers.
Is 17 prime?
17 % 2 = 1
17 % 3 = 2
17 % 4 = 1 <--| approximately the square root of 17 [4.123...]
17 % 5 = 2 <--|
17 % 6 = 5
17 % 7 = 3
The results after sqrt(X), like 17 % 7 and so on, are redundant because they must necessarily multiply with something smaller than the sqrt(X) to yield X.
That is,
A * B = X
if A and B are both greater than sqrt(X) then
A*B will yield a number that is greater than X.
Thus, one of either A or B must be smaller than sqrt(X), and it is redundant to check both of these values since you only need to know if one of them divides X evenly (the even division gives you the other value as an answer)
I hope that helps.
edit: There are more sophisticated methods of checking primality and Java has a built-in "this number is probably prime" or "this number is definitely composite" method in the BigInteger class as I recently learned via another SO answer :]
You need to do some research on algorithms for factorizing large numbers; this wikipedia page looks like a good place to start. In the first paragraph, it states:
When the numbers are very large, no efficient integer factorization algorithm is publicly known ...
but it does list a number of special and general purpose algorithms. You need to pick one that will work well enough to deal with 12 decimal digit numbers. These numbers are too large for the most naive approach to work, but small enough that (for example) an approach based on enumerating the prime numbers starting from 2 would work. (Hint - start with the Sieve of Erasthones)
Here is very elegant answer - which uses brute force (not some fancy algorithm) but in a smart way - by lowering the limit as we find primes and devide composite by those primes...
It also prints only the primes - and just the primes, and if one prime is more then once in the product - it will print it as many times as that prime is in the product.
public class Factorization {
public static void main(String[] args) {
long composite = 600851475143L;
int limit = (int)Math.sqrt(composite)+1;
for (int i=3; i<limit; i+=2)
{
if (composite%i==0)
{
System.out.println(i);
composite = composite/i;
limit = (int)Math.sqrt(composite)+1;
i-=2; //this is so it could check same prime again
}
}
System.out.println(composite);
}
}
You want to iterate from 2 -> n-1 and make sure that n % i != 0. That's the most naive way to check for primality. As explained above, this is very very slow if the number is large.
To find factors, you want something like:
long limit = sqrt(number);
for (long i=3; i<limit; i+=2)
if (number % i == 0)
print "factor = " , i;
In this case, the factors are all small enough (<7000) that finding them should take well under a second, even with naive code like this. Also note that this particular number has other, smaller, prime factors. For a brute force search like this, you can save a little work by dividing out the smaller factors as you find them, and then do a prime factorization of the smaller number that results. This has the advantage of only giving prime factors. Otherwise, you'll also get composite factors (e.g., this number has four prime factors, so the first method will print out not only the prime factors, but the products of various combinations of those prime factors).
If you want to optimize that a bit, you can use the sieve of Eratosthenes to find the prime numbers up to the square root, and then only attempt division by primes. In this case, the square root is ~775'000, and you only need one bit per number to signify whether it's prime. You also (normally) only want to store odd numbers (since you know immediately that all even numbers but two are composite), so you need ~775'000/2 bits = ~47 Kilobytes.
In this case, that has little real payoff though -- even a completely naive algorithm will appear to produce results instantly.
I think you're confused because there is no iff [if-and-only-if] operator.
Going to the square root of the integer in question is a good shortcut. All that remains is checking if the number within that loop divides evenly. That's simply [big number] % i == 0. There is no reason for your Prime function.
Since you are looking for the largest divisor, another trick would be to start from the highest integer less than the square root and go i--.
Like others have said, ultimately, this is brutally slow.
private static boolean isPrime(int k) throws IllegalArgumentException
{
int j;
if (k < 2) throw new IllegalArgumentException("All prime numbers are greater than 1.");
else {
for (j = 2; j < k; j++) {
if (k % j == 0) return false;
}
}
return true;
}
public static void primeFactorsOf(int n) {
boolean found = false;
if (isPrime(n) == true) System.out.print(n + " ");
else {
int i = 2;
while (found == false) {
if ((n % i == 0) && (isPrime(i))) {
System.out.print(i + ", ");
found = true;
} else i++;
}
primeFactorsOf(n / i);
}
}
For those answers which use a method isPrime(int) : boolean, there is a faster algorithm than the one previously implemented (which is something like)
private static boolean isPrime(long n) { //when n >= 2
for (int k = 2; k < n; k++)
if (n % k == 0) return false;
return true;
}
and it is this:
private static boolean isPrime(long n) { //when n >= 2
if (n == 2 || n == 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int k = 1; k <= (Math.floor(Math.sqrt(n)) + 1) / 6; k++)
if (n % (6 * k + 1) == 0 || n % (6 * k - 1) == 0) return false;
return true;
}
I made this algorithm using two facts:
We only need to check for n % k == 0 up to k <= Math.sqrt(n). This is true because for anything higher, factors merely "flip" ex. consider the case n = 15, where 3 * 5 = 5 * 3, and 5 > Math.sqrt(15). There is no need for this overlap of checking both 15 % 3 == 0 and 15 % 5 == 0, when we could just check one of these expressions.
All primes (excluding 2 and 3) can be expressed in the form (6 * k) + 1 or (6 * k) - 1, because any positive integer can be expressed in the form (6 * k) + n, where n = -1, 0, 1, 2, 3, or 4 and k is an integer <= 0, and the cases where n = 0, 2, 3, and 4 are all reducible.
Therefore, n is prime if it is not divisible by 2, 3, or some integer of the form 6k ± 1 <= Math.sqrt(n). Hence the above algorithm.
--
Wikipedia article on testing for primality
--
Edit: Thought I might as well post my full solution (*I did not use isPrime(), and my solution is nearly identical to the top answer, but I thought I should answer the actual question):
public class Euler3 {
public static void main(String[] args) {
long[] nums = {13195, 600851475143L};
for (num : nums)
System.out.println("Largest prime factor of " + num + ": " + lpf(num));
}
private static lpf(long n) {
long largestPrimeFactor = 1;
long maxPossibleFactor = n / 2;
for (long i = 2; i <= maxPossibleFactor; i++)
if (n % i == 0) {
n /= i;
largestPrimeFactor = i;
i--;
}
return largestPrimeFactor;
}
}
To find all prime factorization
import java.math.BigInteger;
import java.util.Scanner;
public class BigIntegerTest {
public static void main(String[] args) {
BigInteger myBigInteger = new BigInteger("65328734260653234260");//653234254
BigInteger originalBigInteger;
BigInteger oneAddedOriginalBigInteger;
originalBigInteger=myBigInteger;
oneAddedOriginalBigInteger=originalBigInteger.add(BigInteger.ONE);
BigInteger index;
BigInteger countBig;
for (index=new BigInteger("2"); index.compareTo(myBigInteger.add(BigInteger.ONE)) <0; index = index.add(BigInteger.ONE)){
countBig=BigInteger.ZERO;
while(myBigInteger.remainder(index) == BigInteger.ZERO ){
myBigInteger=myBigInteger.divide(index);
countBig=countBig.add(BigInteger.ONE);
}
if(countBig.equals(BigInteger.ZERO)) continue;
System.out.println(index+ "**" + countBig);
}
System.out.println("Program is ended!");
}
}
I got a very similar problem for my programming class. In my class it had to calculate for an inputted number. I used a solution very similar to Stijak. I edited my code to do the number from this problem instead of using an input.
Some differences from Stijak's code are these:
I considered even numbers in my code.
My code only prints the largest prime factor, not all factors.
I don't recalculate the factorLimit until I have divided all instances of the current factor off.
I had all the variables declared as long because I wanted the flexibility of using it for very large values of number. I found the worst case scenario was a very large prime number like 9223372036854775783, or a very large number with a prime number square root like 9223371994482243049. The more factors a number has the faster the algorithm runs. Therefore, the best case scenario would be numbers like 4611686018427387904 (2^62) or 6917529027641081856 (3*2^61) because both have 62 factors.
public class LargestPrimeFactor
{
public static void main (String[] args){
long number=600851475143L, factoredNumber=number, factor, factorLimit, maxPrimeFactor;
while(factoredNumber%2==0)
factoredNumber/=2;
factorLimit=(long)Math.sqrt(factoredNumber);
for(factor=3;factor<=factorLimit;factor+=2){
if(factoredNumber%factor==0){
do factoredNumber/=factor;
while(factoredNumber%factor==0);
factorLimit=(long)Math.sqrt(factoredNumber);
}
}
if(factoredNumber==1)
if(factor==3)
maxPrimeFactor=2;
else
maxPrimeFactor=factor-2;
else
maxPrimeFactor=factoredNumber;
if(maxPrimeFactor==number)
System.out.println("Number is prime.");
else
System.out.println("The largest prime factor is "+maxPrimeFactor);
}
}
public class Prime
{
int i;
public Prime( )
{
i = 2;
}
public boolean isPrime( int test )
{
int k;
if( test < 2 )
return false;
else if( test == 2 )
return true;
else if( ( test > 2 ) && ( test % 2 == 0 ) )
return false;
else
{
for( k = 3; k < ( test/2 ); k += 2 )
{
if( test % k == 0 )
return false;
}
}
return true;
}
public void primeFactors( int factorize )
{
if( isPrime( factorize ) )
{
System.out.println( factorize );
i = 2;
}
else
{
if( isPrime( i ) && ( factorize % i == 0 ) )
{
System.out.print( i+", " );
primeFactors( factorize / i );
}
else
{
i++;
primeFactors( factorize );
}
}
public static void main( String[ ] args )
{
Prime p = new Prime( );
p.primeFactors( 649 );
p.primeFactors( 144 );
p.primeFactors( 1001 );
}
}