Reputation: 11
I need to write a recursive method to compute the following series: e = 1+1/1!+1/2!+1/3!+...
This is what I have so far.
public static void main(String[] args)
{ System.out.println("enter n :");
int n =scan.nextInt();
double h = fact(n);
System.out.println(" e = ");
}
public double fact(int n)
{
if (n == 1)
return 1;
else
return ???;
}
}
Upvotes: 1
Views: 3996
Reputation: 11
write the code as below and call it from main class.
public static double recursiveFun(double value){
if (value==1)
return 1.0;
if (value==2){
return (1/(value-1) + 1/value);
}
else
return recursiveFun(value-1) + 1/value;
}
Upvotes: 0
Reputation: 533890
Calculating e^n recursively is very expensive. It is O(n^2) and it is hard to know when to stop. Instead I suggest you do it iteratively.
static final int runs = 20000;
static volatile int exp = 1;
static volatile int n = 18;
static volatile double dontOptimiseAway;
public static void main(String[] args) throws InterruptedException {
System.out.println("Math.exp(1)=" + Math.exp(1));
System.out.println("exp_iter(18)=" + exp_iter(18));
System.out.println("exp_recurse(18)=" + exp_recurse(18));
for (int t = 0; t < 3; t++) {
System.out.printf("exp(1), exp_iter(18), exp_recurse(18) took %,d / %,d / %,d ns on average%n",
timeMathExp(), timeExpIter(), timeExpRecurse());
}
}
public static long timeMathExp() {
long start = System.nanoTime();
for (int i = 0; i < runs; i++)
dontOptimiseAway = Math.exp(exp);
return (System.nanoTime() - start) / runs;
}
public static long timeExpIter() {
long start = System.nanoTime();
for (int i = 0; i < runs; i++)
dontOptimiseAway = exp_iter(n);
return (System.nanoTime() - start) / runs;
}
public static long timeExpRecurse() {
long start = System.nanoTime();
for (int i = 0; i < runs; i++)
dontOptimiseAway = exp_recurse(n);
return (System.nanoTime() - start) / runs;
}
public static double exp_iter(int n) {
double exp = 0, x = 1;
for (int i = 2; i <= n; i++)
exp += (x /= i);
return 2 + exp;
}
public static double exp_recurse(int n) {
return n <= 0 ? 1 : 1.0 / fact(n) + exp_recurse(n - 1);
}
public static double fact(int n) {
return n <= 1 ? 1 : n * fact(n - 1);
}
prints
Math.exp(1)=2.718281828459045
exp_iter(18)=2.718281828459045
exp_recurse(18)=2.7182818284590455
exp(1), exp_iter(18), exp_recurse(18) took 111 / 191 / 760 ns on average
exp(1), exp_iter(18), exp_recurse(18) took 75 / 78 / 558 ns on average
exp(1), exp_iter(18), exp_recurse(18) took 69 / 66 / 552 ns on average
Upvotes: 0
Reputation: 62072
So, assuming the n
input you're taking is the starting denominator for the smallest fraction you'd add...
(For example, given n = 10
, you want to add 1
through 1/10
)
Then you need to set up your method so that when you call fact(10)
, it's going to return the sum of 1/10
plus the result of fact(9)
, or more generically, 1/n + fact(1/n-1);
So, you're looking for something like this:
public double fact(int n) {
if (n < 0) {
return 0.0;
} else if (n == 0) {
return 1.0;
} else {
return (1.0/n + fact(n-1))
}
}
Also, please note the changes to the base cases. When n < 0
, we just return 0.0
, because if I recall correctly, the factorial of any negative number is always 0, right?
Meanwhile, the base case should be n==0
, not n == 1
. Your series starts with 1 + 1/1
. Note that 1
is not 1/0
or 1/nothing
, it's just 1/1
. We can't return 1/n
when n
is 0
. For the series to calculate correctly, we have to add the first return the first element of the series in the case of n = 0
.
And keep in mind, as with all recursive functions, very large values of n
will cause a stack overflow.
Upvotes: 3
Reputation: 24336
Here are a couple of resources:
"Yes you can! But you need to get into a subject called the "Gamma Function", which is beyond this simple page.
Half Factorial
But I can tell you the factorial of half (½) is half of the square root of pi = (½)√π, and so some "half-integer" factorials are:"
More specifically you want the Gamma Function
Apache commons has an implementation of this function.
Discussion on Math Exchange
And here is an implementation from Princeton
public class Gamma {
static double logGamma(double x) {
double tmp = (x - 0.5) * Math.log(x + 4.5) - (x + 4.5);
double ser = 1.0 + 76.18009173 / (x + 0) - 86.50532033 / (x + 1)
+ 24.01409822 / (x + 2) - 1.231739516 / (x + 3)
+ 0.00120858003 / (x + 4) - 0.00000536382 / (x + 5);
return tmp + Math.log(ser * Math.sqrt(2 * Math.PI));
}
static double gamma(double x) { return Math.exp(logGamma(x)); }
public static void main(String[] args) {
double x = Double.parseDouble(args[0]);
System.out.println("Gamma(" + x + ") = " + gamma(x));
System.out.println("log Gamma(" + x + ") = " + logGamma(x));
}
}
Upvotes: 0