factorial method doesn't work well! - java

Hi
this is a factorial method but it prints 0 in the console please help me thanks
public class Demo {
public static void main(String[] args) {
Demo obj = new Demo();
System.out.println(obj.factorial(500));
}
public int factorial(int n) {
int fact = 1;
for (int i = 2; i <= n; i++) {
fact= fact*i;
}
return fact;
}
EDITED:will return Infinity!
public class Demo {
public static void main(String[] args) {
Demo obj = new Demo();
System.out.println(obj.factorial(500));
}
public double factorial(long n) {
double fact = 1;
for (int i = 2; i <= n; i++) {
fact= fact*i;
}
return fact;
}
}

Since 500! equals 1220136825991110068701238785423046926253574342803192842192413588385845373153881997605496447502203281863013616477148203584163378722078177200480785205159329285477907571939330603772960859086270429174547882424912726344305670173270769461062802310452644218878789465754777149863494367781037644274033827365397471386477878495438489595537537990423241061271326984327745715546309977202781014561081188373709531016356324432987029563896628911658974769572087926928871281780070265174507768410719624390394322536422605234945850129918571501248706961568141625359056693423813008856249246891564126775654481886506593847951775360894005745238940335798476363944905313062323749066445048824665075946735862074637925184200459369692981022263971952597190945217823331756934581508552332820762820023402626907898342451712006207714640979456116127629145951237229913340169552363850942885592018727433795173014586357570828355780158735432768888680120399882384702151467605445407663535984174430480128938313896881639487469658817504506926365338175055478128640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 you can't fit it into an int (which ranges up to 2147483647).
Using an int you can only store up to 12!.
Using a long you'll get up to 20!
Using a double you'll get up to 170!.
By convention 0! equals 1;
Here is a solution using BigInteger:
public static BigInteger factorial(int i) {
if (i == 0) {
return BigInteger.ONE;
}
BigInteger n = BigInteger.valueOf(i);
while (--i > 0) {
n = n.multiply(BigInteger.valueOf(i));
}
return n;
}

There's no way you can fit 500! on a 32-bit int.
For calculations involving large numbers, consider using a double or a BigInteger, depending on whether you want an approximate or an exact answer.
(Actually, for 500!, even a double would not be enough: Double.MAX_VALUE is 1.7976931348623157E+308, which will "only" let you go up to 170!)

There are two things you should be looking into if you need to calculate the factorial function:
1) Memoization. This will dramatically speed up your calculations, since the factorial function has a recursive definition. What you do is cache previous calculations, so when you ask for k!, you can get it in one step by calculating k*((k-1)!) if you have (k-1)! cached.
2) Stirling's approximation. If you need to calculate large factorials, you can approximate them very rapidly this way, and with guaranteed bounds on the error, so you can tell whether the approximation will be acceptably close for your application.
If you do neither of these, you will find that there is some relatively small k for which you simply can't calculate k! in a reasonable amount of time.

Grodriguez is right - this is almost certainly caused by integer overflow.
If you test your method with more modest inputs it appears to return the right output:
public static void main(String[] args) {
Demo obj = new Demo();
for (int i = 0; i < 10; i++)
System.out.println(i + "! = " + obj.factorial(i));
}
500! is massive; when testing your function, starting with smaller inputs would be prudent.

500! is way too big to fit a long, or double.
You would have to use other techniques to get this.
But first, what kind of program needs 500!?

There are some very nice optimization for the implementation of factorizations: see for instance luschny.de for a nice implementation of them in Java. Some require more mathematical insight then others... Have fun with the library :-)

Related

Java program which sums numbers from 1 to 100

I have been recently started learning Java and would want to make code that sums the numbers from 1 to 100 (result would be 5050)
The code should go like 1+2+3+4+5+6+7+8+9+10... etc
I have tested it with this code:
public class T35{
public static void main(String[] args) {
int nmb;
for(nmb= 1; nmb<= 100; nmb++){
System.out.println(nmb);
}
}
}
But the result is that it goes from 1 to 100 without adding the numbers.
Not sure if it need to be made with while but could not figure the math for it.
Hey you can find the sum from 1 to 100 like this also. Just a option.
You can use the mathematical formula for sum of numbers i.e n(n+1)/2
public class test {
public static void main(String[] args) {
int i =100;
int sum = (i)*(i+1)/2;
System.out.println(sum);
}
}
nmb++ is equal to nmb = nmb + 1. It only adds one till it's 101, which is when it stops.
You should add a new variable, let's call it total, and sum nmb to it every iteration.
public class T35{
public static void main(String[] args) {
int nmb;
int total = 0;
for(nmb= 1; nmb<= 100; nmb++){
total = total + nmb;
}
System.out.println(total);
}
}
This will do what you want.
You have started to learn Java by implementing a for loop. Unfortunately that is probably the least intuitive syntax in the entire language. It was inherited from c and, while convenient, really makes no sense: the meaning of the three positions bears no resemblance to natural language (unlike if, while, implements etc.). Much better to start with simpler constructs until you get the hang of things.
Java 8 provides a more intuitive (in my opinion) way of representing a group of numbers to add. In your case you don't really want to iterate through all the numbers from 1 to 100. You just want a way to represent all those numbers and then sum them. In Java 8 this concept is represented by a stream of integers: the IntStream class. It provides a handy way of asking for 'all integers between x and y': the rangeClosed method. And it provides a method for adding all the integers together: the sum method.
So your operation could be implemented with a single, simple Java statement:
IntStream.rangeClosed(1, 100).sum();
That seems a pretty straightforward statement to read: give me a stream of integers in the range from 1 to 100 and then sum them. Even better you don't need to declare a variable you have no real use for.
You output the value of nmb that is the numeric value that you iterate on, you don't increment the actual value with the current sum.
You should introduce a local variable before the loop to compute and maintain the actual sum.
Besides, int nmb; could be declared directly in the loop.
Narrowing the scope of variables makes the code more robust.
public class T35{
public static void main(String[] args) {
int sum = 0;
for(int i= 1; i<= 100; i++){
sum += i;
System.out.println(sum);
}
}
}
Use this code. It will print the value like
1+2+3.. + 100 = 5050
public class T35{
public static void main(String[] args) {
int total=0;
StringBuilder stringBuilder=new StringBuilder();
for(int nmb= 1; nmb<= 100; nmb++){
total+=nmb;
stringBuilder.append(nmb);
if(nmb!=100)
stringBuilder.append("+");
}
stringBuilder.append(" = "+total);
System.out.println(stringBuilder.toString());
}
}
public class SumsUpPractice2 {
public static void main(String[] args) {
//
int count, sum;
sum = 0;
for (count = 1;count <= 100; count++) {
sum = sum + count;
}
System.out.println(sum);
}
}
We initialize sum with 0 and add count to it at each iteration.

Using biginteger to find the sequence of sum of powers

Sum(N) =1^1+2^2+3^3+...+N^N
Using Java,
How would I use BigInteger to find the smallest integer N such that the value of Sum(N) is larger than 10^20?
I'm really stuck,please give me some advice
This is what I have so far:
import java.math.BigInteger;
public class PROJECTV1 {
public static void main(String [] args) {
BigInteger bResult= bigFunctionExample_2();
System.out.println(" => result_got:"+ bResult);
System.out.println(); //newline
}// end_main
public static BigInteger bigFunctionExample_2() {
BigInteger bSum = BigInteger.ZERO;
BigInteger bTmp;
String sSum;
// BigInteger bResult =0;
for (int i=1; ; i++) {
bTmp = BigInteger.valueOf(i);
bTmp = bTmp.pow(i); // i^i
bSum = bSum.add(bTmp); // sum = i^i+ (i-1)^(i-1)+ ....
sSum = bSum.toString();
if ( sSum.length() >21) {
System.out.println("i="+i +" bSum ="+bSum);
break;
}//
}//end_for
return bSum; // result
} // end_bigFunctionExample_2
}
Looking at your code, you have a line bTmp.pow(2). That squares the numbers in your series, but you need to raise bTmp to the bTmp power. Java doesn’t seem to want to take a BigInteger as an argument to pow, but you could replace pow with another for loop.
Also, sSum.length() >30 looks like it will only occur if your sum is greater than or equal to 1029. Is there a reason you convert the number to a string each time through the loop, rather than comparing the number to 1020? Perhaps you could put something like bSum > bMax as the test condition in your for loop, rather than leaving it blank and exiting with a break. Then you could make a new BigInteger bMax and set it to 1020 at the start of your code.
For testing, you could set bMax to something small, like 100, and see if your program gives the correct result. You can calculate the first few steps of the series by hand to check your program.
Here is a clue computing some factorials:
import java.math.*;
public class FactorialBig {
public static BigInteger factorial(BigInteger n) {
if (n.equals(BigInteger.ZERO))
return BigInteger.ONE;
else
return n.multiply(factorial(n.subtract(BigInteger.ONE)));
}
public static void main(String[] args) {
for (int n = 0; n < 20; n++) {
BigInteger f = factorial(new BigInteger(new Integer(n).toString()));
System.out.printf("factorial(%2d) = %20s%n", n, f.toString());
}
}
}
You know you should save the above as a file named "FacotrialBig.java".

Can't Generate Large Prime Numbers

I'm trying to generate large prime numbers in Java. I use BigIntegers for this. Here is my code to generate and store 10 prime numbers inside an array.
public static void primeGenerator() {
BigInteger[] primeList = new BigInteger[10];
BigInteger startLine = new BigInteger("10");
int startPower = 6;
BigInteger endLine = new BigInteger("10");
int endPower = 9;
int j = 0;
for (BigInteger i = fastExp(startLine,startPower);
i.compareTo(fastExp(endLine,endPower)) <= 0;
i = i.add(BigInteger.ONE)) {
if (checkPrimeFermat(i) == true && j < 10) {
primeList[j] = i;
j++;
}
}
System.out.println(primeList[0]);
System.out.println(primeList[1]);
System.out.println(primeList[2]);
System.out.println(primeList[3]);
System.out.println(primeList[4]);
System.out.println(primeList[5]);
System.out.println(primeList[6]);
System.out.println(primeList[7]);
System.out.println(primeList[8]);
System.out.println(primeList[9]);
}
I wrote my own fastExp function to generate numbers faster. Here are my other functions.
public static BigInteger getRandomFermatBase(BigInteger n)
{
Random rand = new Random();
while (true)
{
BigInteger a = new BigInteger (n.bitLength(), rand);
if (BigInteger.ONE.compareTo(a) <= 0 && a.compareTo(n) < 0)
{
return a;
}
}
}
public static boolean checkPrimeFermat(BigInteger n)
{
if (n.equals(BigInteger.ONE))
return false;
for (int i = 0; i < 10; i++)
{
BigInteger a = getRandomFermatBase(n);
a = a.modPow(n.subtract(BigInteger.ONE), n);
if (!a.equals(BigInteger.ONE))
return false;
}
return true;
}
public static void main(String[] args) throws IOException
{
primeGenerator();
}
public static BigInteger fastExp (BigInteger x, int n){
BigInteger result=x;
int pow2=powof2leN(n);
int residue= n-pow2;
for(int i=1; i<pow2 ; i=i*2){
result=result.multiply(result);
}
for(int i=0 ; i<residue; i++){
result=result.multiply(x);
}
return result;
}
private static int powof2leN(int n) {
for(int i=1; i<=n; i=i*2){
if(i*2>2)
return 1;
}
return 0;
}
}
So the problem is when I try it with small numbers (for example startPower=3, endPower=5) it generates and prints prime numbers. But when I try it with big numbers (for example startPower=5, endPower=7) it doesn't generate anything. How can I improve my code to work with large numbers?
Thank you
First of all, I would like to point out that you did not write this code. You stole it from here and claimed that you wrote it, which is incredibly unethical.
The code is correct. It's just slow. As you increase the power, the code takes increasingly longer. There are two reasons why this occurs:
The Fermat test takes increasingly longer to apply.
BigInteger operations take increasingly longer to execute.
The Fermat test grows like O(k × log2n × log log n × log log log n). BigInteger's addition and subtraction grow like O(n). Obviously, BigInteger is what is slowing you down.
Below is a profile of your code with the power set from 5 to 7.
If you want your code to produce larger and larger primes, you should focus on reducing the number of operations you do on BigIntegers. Here is one such improvement:
Take n.subtract(BigInteger.ONE) outside of your for loop. The result does not need to be calculated many times.
Further suggestions will have to come from the Mathematics folks over on Mathematics Stack Exchange.
Here is a much simpler solution for finding large primes -
BigInteger big = new BigInteger("9001");//or whatever big number you want to start with
BigInteger[] primes = new BigInteger[10];
for(int i=0;i<10;i++){
primes[i]=big=big.nextProbablePrime();
}
It has some limitations outlined here, but based on your code it should be more than enough.
you can use BigInteger(int bitLength, int certainty, Random rnd) constructor
BigInteger b= new BigInteger(20, 1, new Random());
It will generate a prime number for you. bitLength specifies the number of digits you want in your BigInteger, certainity specifies the amount of certainity you want that your BigInteger should be prime.

How to solve this summation in a recursive way

Today, my teacher asked us to implement the next expression using recursion in Java (where n is a value asked to the user):
It is possible? I can't find a proper solution for this problem, but I think I will need two recursive methods.
UPDATE
So far I have done this:
public static double sumatorio(int n){
if(n==1)
return 1;
else{
return (1 + ((n-1) * segundoSumatorio(n))) + sumatorio(n-1);
}
}
public static double segundoSumatorio(int n){
if(n==1)
return 1;
else
return 1/(double)n + segundoSumatorio(n-1);
}
It looks like it's correct, but when n=3 or greater, the result is not exact. Someone knows why?
Maybe there is an error related with losing precision.
I really appreciate any help you can provide.
Hints:
Yes. One possible solution does involve two recursive methods.
(And it is a good solution ... )
Factor the problem (and the solution) into two parts; e.g. the complete "sigma" and the embedded "sigma".
Here is your code fixed. Note how the 2nd sumatorio needs 2 parameters,
and how I don't change the second parameter while calling it recursively.
This is what your formula says and not what you implemented.
This is not a precision error, you could have figured that out
because this error sounds too big for a precision error for such
small values of n.
public class Test {
public static void main(String a[]) throws Exception {
System.out.println(sumatorio(1));
System.out.println(sumatorio(2));
System.out.println(sumatorio(3));
System.out.println(sumatorio(4));
}
public static double sumatorio(int n){
return sumatorio(n ,n);
}
public static double sumatorio(int n, int m){
if(n==1)
return 1;
else{
return (1 + ((n-1) * segundoSumatorio(m))) + sumatorio(n-1, m);
}
}
public static double segundoSumatorio(int n){
if(n==1)
return 1;
else
return 1/(double)n + segundoSumatorio(n-1);
}
}
If this task is too hard for you, try splitting it in smaller chunks. The question asks for a summation, implemented by recurse. I am confident you can do summation by implementing a loop. Something like:
int sum = 0;
for(int i = 1; i < n; i++){
sum = sum+i;
}
This will sum all numbers from 1 to (n-1).
You can convert the loop into recursion by writing a simple adding method:
int sum = 0;
int doSum(int n){
if(n <= 1){
return 1;
}
else{
return n + doSum(n - 1);
}
}
sum = doSum(n);
From here on I think you should be able to catch up.
Splitting the problem into smaller subproblems is a technique used by ALL programmers. Start small and easy, adding complexity as you go.

Basic Java Recursion Method

I am having a lot of trouble with this basic recursion problem in java; any pointers would be great.
"Write a static recursive method to print out the nth term of the
geometric sequence: 2, 6, 18, 54."
From what I can gather, somewhere in the code I should be recursively multiplying something by 3, but I'm struggling to figure out how to do this. I know I need a termination statement, but when does that occur? Do I need a helper method?
A Recursive Function is a function whose implementation references itself. Below is some funny example:
public class Inception {
public void dream() {
boolean enoughDreaming = false;
//Some code logic below to check if it's high time to stop dreaming recursively
...
...
if(!enoughDreaming) {
dream(); //Dream inside a Dream
}
}
}
And the solution for your problem:
public class GeometricSequence {
public static void main(String[] args) {
//Below method parameters - 5 = n, 1 = count (counter), res = result (Nth number in the GP.
System.out.println(findNthNumber(5, 1, 2));
}
public static int findNthNumber(int n, int count, int res) {
return ((count == n)) ? res : findNthNumber(n, count+1, res *3);
}
}
EDIT:
The above class uses "int", which is good only for small numbers (because of Integer Overflow problem). The below class is better for all types/numbers:
public class GeometricSequence {
public static void main(String[] args) {
//Below method parameters - 5 = n, 1 = count (counter), res = result (Nth number in the GP.
System.out.println(findNthNumber(2000, 1, new BigInteger("2")));
}
public static BigInteger findNthNumber(int n, int count, BigInteger res) {
return ((count == n)) ? res : findNthNumber(n, count+1, res.multiply(new BigInteger("3")));
}
}
This is the simplest example of recursion.
You need a method declaration.
You need to check if the end has been reached.
Otherwise you need to call the method again with an operation which makes the difference between one term and the next.
Yes, you need a termination condition - basically when you've taken as many steps as you need. So consider how you want to transition from one call to another:
How are you going to propagate the results so far?
What extra state do you need to keep track of how many more steps you need to take?
What are you going to return from the method?
Here's a C# example (I know your doing Java but it's pretty similar)
public static void Recursive(int counter, int iterations, int value, int multiplier)
{
if (counter < iterations)
{
Console.WriteLine(value);
counter++;
Recursive(counter, iterations, (value * multiplier), multiplier);
}
}
So when you run the function you enter the parameters
"counter" will always be 0 when you first call it
"iterations" is the value of n
"value" is your starting value, in your case 2
"multiplier" is how much you want to multiply by each iteration, in your case 3
Every time it runs it will check to see if counter is less than iterations. If it is more, the value is printed, the counter is incremented, the value is multiplied by the multiplier and you add the same parameters back in to the function.
A recursive solution: Seq(1) is the first element of the sequence .... Seq(n-th)
public static void main(String args[]) throws Exception {
int x = Seq(3); //x-> 18
}
public static int Seq(int n){
return SeqRec(n);
}
private static int SeqRec(int n){
if(n == 1)
return 2;
else return SeqRec(n - 1) * 3;
}
Non-Recursive solution:
public static int Non_RecSeq(int n){
int res = 2;
for(int i = 1; i < n; i ++)
res *= 3;
return res;
}
public static void main(String args[]) throws Exception {
int x = Non_RecSeq(3); //x-> 18
}

Categories