Reputation: 367
I'm trying recursion.
I just want the output to be the result of multiplying the input by 2: output = 2*input
.
It should be like this, why is it not working?
function fE(f) {
if(f < 0){
return 1;}
else{
return f + fE(f);}
}
console.log(fE(3)); // output 6
console.log(fE(6)); // 12
Upvotes: 0
Views: 188
Reputation: 135227
Great answers from @torazaburo and @nnnnnn – they're practical and should solve your immediate problem. I'll offer some other alternatives in hope that these will help your brain think about recursive procedures in a variety of ways.
Another common recursion technique is using state variables in an auxiliary function
function mult (x, y) {
function aux (result, counter) {
if (counter === 0)
return result
else
return aux (result + x, counter - 1)
}
return aux (0, y)
}
console.log(mult (5, 4)) // 20
Here's another technique that uses continuation passing style
function multk (x, y, k) {
if (y === 0)
k (0)
else
multk (x, y - 1, function (result) { k (result + x) })
}
multk (5, 4, function (result) { console.log(result) /* 20 */ })
And here's a nutty boiled down version that uses nothing more than primitive +1
and primitive -1
. It may seem complicated but I constructed it for you so that you can see how more complex recursive procedures can be built out of smaller ones. If you can follow this code, it should help you gain a greater understanding of recursion.
(I added some console.log
lines so you can get a better visualization of what's happening. You wouldn't want to leave these in your code.)
function add1 (x) {
return x + 1
}
function sub1 (x) {
return x - 1
}
function add (x, y) {
console.log('adding:', x, y)
if (y === 0)
return x
else
return add (add1(x), sub1(y))
}
function mult (x, y) {
function aux (result, counter) {
console.log('multiplying:', result, counter)
if (counter === 0)
return result
else
return aux (add(result, x), sub1(counter))
}
return aux (0, y)
}
console.log('result:', mult (5, 4)) // 20
And the same thing using undelimited continuations
function add1 (x, k) {
k (x + 1)
}
function sub1 (x, k) {
k (x - 1)
}
function addk (x, y, k) {
console.log('adding:', x, y)
if (y === 0)
k (x)
else
add1 (x, function (x1) {
sub1 (y, function (y1) {
addk (x1, y1, k)
})
})
}
function multk (x, y, k) {
function aux (result, counter, k) {
console.log('multiplying:', result, counter)
if (counter === 0)
k (result)
else
addk (result, x, function (result1) {
sub1 (counter, function (counter1) {
aux (result1, counter1, k)
})
})
}
aux (0, y, k)
}
multk (5, 4, function (result) { console.log('result:', result) /* 20 */ })
Upvotes: 1
Reputation:
Recursion involves a base case, which in your case is an input of zero. The answer in that case is zero. Otherwise, reduce the problem to the sum of two and the result of calling the function recursively with an argument one less. If the input is negative, return the negation of the result of the negation of the input.
function fE(f) {
if (f === 0) return 0;
else if (f < 0) return -fE(-f);
else return 2 + fE(f - 1);
}
console.log(fE(3)); // output 6
console.log(fE(6)); // 12
console.log(fE(-4)); // -8
Your code:
function fE(f) {
if(f < 0){
return 1;}
else{
return f + fE(f);}
}
has the following problems:
fE(f)
will cause an infinite loop, right?f
to the result of recursing; you want to add 2, which is where you get the doubling effect.Upvotes: 3
Reputation: 150030
Your function as shown will try to recurse infinitely, because the recursive call on the line with f + fE(f)
passes the same value of f
through each time, which means the if
test on the first line will always fail.
It doesn't make any sense to implement this recursively, because you can calculate the correct result with one line of code:
function fE(f) { return 2 * f; }
Perhaps a better example of a recursive function (for learning purposes) would be a function that multiples any two numbers together via a larger number of recursive calls:
multiply(10, 3) // return 30
...again that could easily be implemented in one line:
function multiply(a, b) { return a * b; }
...but you could do it with recursion like this:
function multiply(a, b) {
console.log(a, b);
if (b === 0)
return 0;
else if (b === 1)
return a;
else if (b < 0)
return -multiply(a, -b);
else
return a + multiply(a, b-1);
}
multiply(12, 4) // 48
multiply(5, -3) // -15
multiply(3, 0) // 0
Notice that each time the function calls itself it passes a different value in the second argument, so that eventually the else if (b === 1)
condition will be true and the recursion will stop. I've included a console.log(a,b)
so that you can see for yourself what the arguments are on each call.
Upvotes: 1