I'm studying java programming by going through Computer Science at the Saylor academy's webpage. I got to the point where I'm learning about debugging programs in NetBeans, and there is a program that computes and prints the factorial of n (=1*2*3*...*n). The text says that there is a logical error in the program but nothing about where it is. And I can't seem to figure out where the logical error is.
Anyone who can help? The program code:
/** Compute the factorial of n */
public class Factorial {
// Print factorial of n
public static void main(String[] args) {
int n = 20;
int factorial = 1;
// n! = 1*2*3...*n
for (int i = 1; i <= n; i++) {
factorial *= i;
}
System.out.println("The Factorial of " + n + " is " + factorial);
}
}
20! is 2,432,902,008,176,640,000 (~ 2*10^18), much larger than the largest possible number that can be stored in an int, which is about 2 billion. This code will overflow and display an incorrect answer.
The correction to be made is to change the declaration of factorial from int to long.
The value of 20! is much bigger than the int type can store.
Use long instead of int
There might not be any Syntax Errors. But there is some error which is unknown to the compiler. Hence it hand overs this problem to OS and the OS immediately terminates the program. This is usually the case with C. Java was made even more powerful by introducing effective EXCEPTION HANDLING to overcome such type of problems i.e., logical errors.
As others have pointed out, the data type is your limitation in this case.
Should you wish to compute large maths, you should use a custom data type specifically suited to represent large numbers.
If you wish to learn about such an implementation, I highly recommend you read Paŭlo Ebermann's incredibly thorough answer to this StackOverflow question.
If you have no interest in how the implementation works but simple want to perform a large integer calculation, you can use Java's BigInteger data type.
Related
I recently started preparing for job interviews and came across with this example question which ask us to find how many bits are set to 1 in a number and answer code block.
The Following program tests bits one at a time starting with the least
significant bit. It illustrates shifting and masking; it also shows
how to avoid hard-coding the size of the integer word
public static short countBits(int x){
short numBits = 0;
while (x != 0){
numBits += (x & 1);
x = x >>> 1;
}
return numBits;
}
What I do not understand here is how this code avoiding hard-coding. The wikipedia article says about hard coding;
Hard coding is the software development practice of embedding data
directly into the source code of a program or other executable object,
as opposed to obtaining the data from external sources or generating
it at runtime.
In this article it says we are hard-coding if we are taking data directly from source code. Which is exactly what we are doing in the method. We are taking the data from source code:
Parameter → int x is hard coded.
The second part I do not understand is how we are not hard coded size of the integer word.
What is that mean?
You are not doing x&1+(x>>>1)&1+(x>>>2)&1+...(x>>>63)&1 or for(int i=0; i<64; i++) { ... }. These both would assume that integers have 64 bits (which btw would take unnecessarily more time as integers only use 32 bits in java, but that's the reason you want to avoid hard-coding). Your method doesn't care how many bits an integer has, it just cares that there are still 1's somewhere in it.
Data type to hold a very large number say 1000 or more digits?
I need to find the factorial of a large number say 100000000.
My factorial program works nice for a smaller number.
long factorial(int x)
{
long fact=1;
if(x<0)
{
System.out.println("Incorrect input, enter a positive number");
fact=0;
}
if(x==0)
fact=1;
if(x>0)
{
fact=x;
fact=fact*factorial(x-1);
}
return fact;
}
You need a BigInteger. It can hold an arbitrarily large number.
But in your case 100000000! is such a huge number, that nothing can help.
You should use a log of gamma function, since gamma(n) = (n-1)! Far more efficient than your naive, student way of doing things. It'll be a double in that case, and the natural log will grow more slowly than the value does.
Recursion? Please. Your problem won't be the size of the value you pass back - you'll get too many stack frames and out of memory error long before that.
While BigInteger will theoretically handle such a value, you won't be able to compute it in practise.
First, your algorithm uses recursion, so you'd need 100.000.000 recursive calls of factorial. You'll get stack overflow far before computing the result. You'd have to modify your algorithm to avoid recursion (use a loop for example).
Second, the result will be huge. Using formulas for approximating factorials such as
log n! ~~ n log(n/e)
we can conclude that your number will have more than 750.000.000 digits. While with some luck you might be able to fit it into your memory, you will certainly not be able to compute the number in any reasonable time. Just imagine - you'll have to perform 100.000.000 multiplications with numbers that have hundreds of millions of digits.
Before I get blasted for not following the rules, I DID utilize the search function and see that there are multiple threads on this exact problem. However, none of them answered my specific question.
I'm working on Euler problem #3, where I need to find the highest prime factor of 600851475143. I don't need help solving the problem. I have made a brute force method (could be better, I know) for solving it.
The program returns correctly for all of the tests that I did with smaller numbers (7 digits and less). However, when I enter 600851475143 as a long input, my program never gives me a return. Is my number simply too big the be entered? What could be causing this to happen? I originally thought it was because I was using int tags instead of long, but changing those didn't alter my result.
I'm sure this is simple and I'm missing it, but I am very curious as to what's happening. Thank you in advance :)
//Euler 3: Largest Prime Factor
import java.io.*;
import java.util.Scanner;
import java.lang.Math;
public class Euler3
{
public static void main(String[] args)
{
Scanner scn = new Scanner(System.in);
System.out.println("Enter a number!");
// Create scanner
long numberInput=scn.nextLong();
//Can't have a factor higher than it's square root
double limit=Math.floor(Math.sqrt(numberInput));
// System.out.println(limit);
//Start testing from the highest number possible
for(long i=(numberInput-1);i>0; i--)
{
if(numberInput%i==0)
System.out.println(i+" is prime: "+isPrime(i));
}
} //End Main
public static boolean isPrime(long n)
{
//check if n is a multiple of 2
if (n%2==0) return false;
//if not, then just check the odds
for(int i=3;i*i<=n;i+=2)
{
if(n%i==0)
return false;
}
return true;
}
}
To verify if a number is Prime or not, use the Sieve of Eratosthenes, it will run much faster compared to your naive isPrime method. I won't provide any implementation hint due to this phrase: I don't need help solving the problem.
Also, there could be other hints that you missed. I recommend you to review the problem statement:
What is the largest prime factor
A long variable can easily fit your desired value into it
long: The long data type is a 64-bit signed two's complement integer. It has a minimum value of -9,223,372,036,854,775,808 and a maximum value of 9,223,372,036,854,775,807 (inclusive). Use this data type when you need a range of values wider than those provided by int.
The problem is that your algorithm is not an efficient one. As has already been mentioned, use the Sieve of Eratosthenes
The problem is not in the isPrime method but in the loop you use to call it. You count down from your number n with increments of 1, and you call isPrime only for divisors of n: it will take n/2 steps before you get to the first potential divisor of n - so, in the order of 10^12 steps for your example n.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Calculate the factorial of an arbitrarily large number, showing all the digits
This question might be asked thousand times here. I am repeating my question with a modification. I want to calculate factorial of a large number (max range of the number=10^6). Generally we uses a for loop from i=1 to i=number and every time multiplying the old value to the new value. This is fine for small numbers but what if i have a large number? The range of for loop is increased now. Java primitive data type int, long can't handle the resultant large number. They simply overflows. Although i knew about BigInteger class, which can handle this large output but still for loop is not suiting better here for me. Can somebody please suggest me any tick, any hack to calculate factorial of a number? Below is the simple program which works fine for small number-
public long getFactorial(long number) {
long factorial = 1;
for (long i = 1; i <= number; ++i) {
factorial *= i;
}
return factorial;
}
Understand that the value is in the range of 105565708. It's going to take up about two megabytes of space, all by itself.
That said, Guava's BigIntegerMath.factorial(int) is good enough to handle it, and more importantly, it's actually been optimized for large factorials -- it'll do significantly better than a straightforward for loop. (Disclosure: I contribute to Guava...and wrote much of BigIntegerMath.factorial myself.)
That said, I wouldn't exactly call it fast -- my benchmarks indicate an average of 414ms for a factorial in that range -- but there isn't going to be a truly fast solution, not without extremely heavy-duty bignum libraries, and I wouldn't expect even those to be significantly faster.
That's if you need the exact value. If you can settle for the logarithm, then yeah, either use Apache's logGamma(n+1) to get ln(n!), or approximate it yourself:
double logFactorial = 0;
for (int i = 2; i <= n; i++) {
logFactorial += Math.log(i);
}
Some rounding error will probably accumulate, but it's supposed to be an approximation anyway.
You can use an approximation function called Stirling's Formula for such large values of n.
You can refer to my answer here for more details:
https://softwareengineering.stackexchange.com/questions/134968/number-of-combinations/134972#134972
Use the Gamma function. Gamma(i + 1) = i!
org.apache.commons.math.special provides it for Java.
What people typically do is to calculate log(Gamma(i+1)) and then work in log-space (multiplications become additions, etc.).
Here are some other methods to calculate the factorial quickly: http://www.luschny.de/math/factorial/FastFactorialFunctions.htm
You use BigInteger for factorial, and you still only need a long for i, the loop variable. i only has to go up to 1000000. What's the problem?
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Fast modulo 3 or division algorithm?
Everyone knows that modulo arithmetic can be a huge drawback on performance. Does anyone know of a good alternative for x%3 operations? I know that one exists for x%2, but I really need one for modulo 3 since I want to alternate between three buffers in a for loop.
Thanks!
Well instead of the usual "measure it" stuff an actual answer - because that stuff is actually real fun math. Although the compiler could and probably does this as well (at least modern optimizing c++ compilers, javac certainly won't and I've got no idea if the JVM does this) - so better check if it isn't already doing the work for you.
But still fun to know the theory behind the optimization: I'll use assembly because we need the higher 32bit word of a multiplication. The following is from Warren's book on bit twiddling:
n is the input integer we want the modulo from:
li M, 0x55555556 ; load magical number (2^32 + 2) / 3
mulhs q, M, n ; q = higher word of M * n; i.e. q = floor(M*n / 2^32)
shri t, n, 31 ; add 1 to q if it is negative
add q, q, t
Here q contains the divisor of n / 3 so we just compute the remainder as usual: r = n - q*3
The math is the interesting part - latex would be rather cool here:
q = Floor( (2^32+2)/ 3 * (n / 2^32) ) = Floor( n/3 + 2*n/(3*2^32) )
Now for n = 2^31-1 (largest n possible for signed 32bit integers) the error term is less than 1/3 (and non negative) which makes it quite easy to show that the result is indeed correct. For n = -2^31 we have the correction by 1 above and if you simplify that you'll see that the error term is always larger than -1/3 which means it holds for negative numbers as well.
I leave the proof with the error term bounds for the interested - it's not that hard.
If it's in a straight loop, no need to calculate a modulo. Hold a second int var that you reset every 3 steps.
int i, bn = 0;
for(i=0; i<whatever; i++) {
...
if(++bn == 3) bn = 0;
}
And that is not a premature optimisation, it's avoiding unecessary calculation.
EDIT: It was stated in OP that he was using a loop to switch between buffers, so my solution looks quite appropriate.
As for the downvote, if it was a mistake, no problem.
If 3 is known at compile time, then the compiler will generate the 'tricks' to do it as efficiently as possible. Modulo takes much longer when the divisor is unknown until run-time.