1

I am trying to make a program which calculates double factorial (example - n=3, => (3!)! = 6! = 720) but i have some issues with recursion bottom and i have stack overflow exception.

public static long df(long n) {
    if (n == 1) {
        return 1;
    } else {
        return df(n * df(n - 1));
    }
}

public static void main(String[] args) {
    System.out.println(df(3));
}
1
  • Be careful terminology-wise, double factorial has a specific meaning where n!! is the product from 1 up to n of numbers that share the same parity (odd/even) as n. What you want to do is more like nest calls to factorial. Commented Nov 22, 2018 at 0:58

4 Answers 4

3

You're encountering an infinite loop with df(n * df(n - 1));

n * df(n-1) will compute the factorial, and you're inadvertently feeding your answer back into the recursive method, causing it to go on forever

Change

return df(n * df(n - 1));

to

return n * df(n - 1);

and you should get the correct result for factorials


Once you have this working recursive factorial method, it becomes much easier to create a double factorial by just using df(df(3))

Sign up to request clarification or add additional context in comments.

3 Comments

The solution which you suggest calculates a factorial recursively - 3! = 6. But i am trying to calculate this (3!)! = 6! = 720. I am trying to calculate the factorial twice recursively.
@NoSuchUserException It does not look like there is a good way to do it from one method, but just using df(df(input)) should give you what you want
@ phflack Thank you !
1

I think you should use mutual recursion with the help of factorial.

The general g-factorial function can compose factorial g times:

public static long gf(long n, long g) {
    if (g == 1){
        return fact(n);
    }
    return fact(gf(n, g - 1));
}

The specific double factorial can be gf(n, 2):

public static long df(long n) {
    return gf(n, 2);
}

And the factorial helper function:

public static long fact(long n) {
    if (n == 1) {
        return 1;
    } else {
        return n * fact(n - 1);
    }
}

Now test:

public static void main(String[] args) {
    System.out.println(df(3));
}

Comments

0

We can do:

public static long factorial(long n) {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}

public static long twice_factorial(long n) {
    return factorial(factorial(n));
}

And, if needed, with some trickery turn this into a single method:

public static long twice_factorial(long n) {

    return new Object() {
        long factorial(long n) {
            return (n <= 1) ? 1 : n * factorial(n - 1);
        }

        long twice_factorial(long n) {
            return factorial(factorial(n));
        }
    }.twice_factorial(n);
}

But this is a useless function as it's only good for n < 4 -- once we reach (4!)!, we exceed the limit of Java's long type:

(4!)! = 24! = 620,448,401,733,239,439,360,000
Java 'long' +max  = 9,223,372,036,854,755,807

If you want this function to be useful, you might use a floating approximation equation instead. But calling approximate factorial again on an approximation probably doesn't make much sense. You'd want a floating approximation equation for the nested factorial value itself.

Or, we can switch to BigInteger:

import java.math.BigInteger;

public class Test {

    public static BigInteger factorial(BigInteger n) {
        return (n.compareTo(BigInteger.ONE) <= 0) ? n : n.multiply(factorial(n.subtract(BigInteger.ONE)));
    }

    public static BigInteger twice_factorial(BigInteger n) {
        return factorial(factorial(n));
    }

    public static void main(String[] args) {
        System.out.println(twice_factorial(new BigInteger(args[0])));
    }
}

USAGE

> java Test 4
620448401733239439360000
>

But this only gets to (7!)! before we get java.lang.StackOverflowError! If we want to go further, we need to dump the recursion and compute the factorial iteratively:

public static BigInteger factorial(BigInteger n) {
    BigInteger result = BigInteger.ONE;

    while (n.compareTo(BigInteger.ONE) > 0) {
        result = result.multiply(n);

        n = n.subtract(BigInteger.ONE);
    }

    return result;
}

USAGE

> java Test 8
34343594927610057460299569794488787548168370492599954077788679570543951730
56532019908409885347136320062629610912426681208933917127972031183174941649
96595241192401936325236835841309623900814542199431592985678608274776672087
95121782091782285081003034058936009374494731880192149398389083772042074284
01934242037338152135699611399400041646418675870467025785609383107424869450
...
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000
> 

Comments

-2

Firstly, define your factorial function:

Via Jupyter:

#include <iostream>
std::cout << "some output" << std::endl;

long fac(long n) {
    if( n == 1)
        return 1;
    else
        return n * fac((n-1));
}

And after define your function:

long double_fac(long n)
{
    long step_one = fac(n);
    return fac(step_one);
}

Factorielle-Algorythme

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.