C
C#12mo ago
McMahone

❔ Recursive Multiplier

Hi, when I try to write this example by modifying the method return type to int, I don't get the same output as the void return type. Shouldn't this give the same result? Also, why can't I use Console.WriteLine(RepeatMultiply(1,2,4000)); to output the result in the void method example when calling the method from Main? Sorry if there is something obvious that I don't get. I'm very new to programming.
42 Replies
mtreit
mtreit12mo ago
Do you see that green squiggle? Hover your mouse over it And read what it says Then look at your code again
McMahone
McMahone12mo ago
Yes, CS0162: unreachable code. Does that mean code exits before reaching this part?
mtreit
mtreit12mo ago
It's saying that it is impossible for that line of code to ever execute. Do you see why?
McMahone
McMahone12mo ago
Is it because of the return code above?
mtreit
mtreit12mo ago
Yes.
mtreit
mtreit12mo ago
Jump statements - break, continue, return, and goto
C# jump statements (break, continue, return, and goto) unconditionally transfer control from the current location to a different statement.
mtreit
mtreit12mo ago
return exits the function A recursive function usually returns the result of calling itself.
McMahone
McMahone12mo ago
Ohh now I understand. Is it possible to get the same result without using the void method?
mtreit
mtreit12mo ago
Sure Did you figure it out?
McMahone
McMahone12mo ago
I tried without returning anything, but now it says the method needs a return value. Just tried to call RepeatMultiply(x,multiplier, limit) inside the method
mtreit
mtreit12mo ago
How do you return the result of a function calling itself?
McMahone
McMahone12mo ago
I am returning the repeatmultiply(x, multiplier, liit)
mtreit
mtreit12mo ago
Show the code Use $code
MODiX
MODiX12mo ago
To post C# code type the following: ```cs // code here ``` Get an example by typing $codegif in chat If your code is too long, post it to: https://paste.mod.gg/
mtreit
mtreit12mo ago
$codegif
McMahone
McMahone12mo ago
namespace RecursiveExample
{
class Program
{
public static int RepeatMultiply(int x, int multiplier, int limit)
{
if (x > limit || x <= 0)
{
return 0;
}

x = x * multiplier;

return RepeatMultiply(x, multiplier, limit);


}
static void Main(string[] args)
{

Console.WriteLine(RepeatMultiply(1,2,4000));

}
}
}
namespace RecursiveExample
{
class Program
{
public static int RepeatMultiply(int x, int multiplier, int limit)
{
if (x > limit || x <= 0)
{
return 0;
}

x = x * multiplier;

return RepeatMultiply(x, multiplier, limit);


}
static void Main(string[] args)
{

Console.WriteLine(RepeatMultiply(1,2,4000));

}
}
}
mtreit
mtreit12mo ago
Do you know what a base case is in a recursive function?
McMahone
McMahone12mo ago
kind off isn't my if statement the base case here?
mtreit
mtreit12mo ago
The base case is what causes the recursive function to terminate and return the final value that was calculated. And yes, that's your if statement. But is your base case returning the final value? No, it's returning 0. So once you get to the base case the function just always return 0. You might want to make two if statements - one to check for less than or equal to zero, a second to handle the base case of reaching the limit. Maybe that will make it more clear. Ask in #help-0 , this channel is for @Kobra 's question 🙂
McMahone
McMahone12mo ago
I tried breaking down the if statement into two ifs but can't understand what to do if the limit is reached.
if (x <= 0)
{
return 0;

}
if (x >= 4000)
{
return 0;
}

Console.WriteLine(x);
x = x * multiplier;
return RepeatMultiply(x, multiplier, limit)
if (x <= 0)
{
return 0;

}
if (x >= 4000)
{
return 0;
}

Console.WriteLine(x);
x = x * multiplier;
return RepeatMultiply(x, multiplier, limit)
I am basically doing the same thing before breaking the if statements
mtreit
mtreit12mo ago
Don't return 0 in the base case.
McMahone
McMahone12mo ago
return limit? Sorry, I feel so dumb right now
mtreit
mtreit12mo ago
Recursion is a little tricky at first, don't worry about it. But ultimately the point of this function is to do what? Compute a result (in this case, the value of doing a series of multiplications.) In the base case, return the result. limit is not the result. It never changes.
McMahone
McMahone12mo ago
so return x?
mtreit
mtreit12mo ago
🎉
McMahone
McMahone12mo ago
But it still prints out 4096
mtreit
mtreit12mo ago
What's your final code and what did you expect it to print out?
McMahone
McMahone12mo ago
I want the last value before reaching 4000 to be printed out and then terminate itself exactly like the example with void method
mtreit
mtreit12mo ago
Ok, so think about how you might accomplish that. One approach would be something like: check if multiplying will satisfy your base case and return the accumulated result (not including the latest multiplication) if it does. Only assign the result of the mulitplication to x and recurse if it does not satisfy the base case. You might find a temporary variable useful.
var tmp = x * multiplier;
var tmp = x * multiplier;
McMahone
McMahone12mo ago
Thanks for the tip
using System;

namespace RecursiveExample
{
class Program
{
public static int RepeatMultiply(int x, int multiplier, int limit)
{
if (x <= 0)
{
return 0;

}
if (x * multiplier > 4000)
{
return x;
}

Console.WriteLine(x);
var temp = x * multiplier;
x = temp;
return RepeatMultiply(x, multiplier, limit);

}

static void Main(string[] args)
{

Console.WriteLine(RepeatMultiply(1,2,4000));

}
}
}
using System;

namespace RecursiveExample
{
class Program
{
public static int RepeatMultiply(int x, int multiplier, int limit)
{
if (x <= 0)
{
return 0;

}
if (x * multiplier > 4000)
{
return x;
}

Console.WriteLine(x);
var temp = x * multiplier;
x = temp;
return RepeatMultiply(x, multiplier, limit);

}

static void Main(string[] args)
{

Console.WriteLine(RepeatMultiply(1,2,4000));

}
}
}
@mtreit Thank you for your help and patience. I am so glad for people like you, who have the patience to learn newbies like me. I really appreciate it
mtreit
mtreit12mo ago
Your temp variable isn't necessary there. I was suggesting using a temp variable so you don't do the multiplication twice. (Which is a very small performance optimization) Also, I assume hard-coding 4000 was just for debugging, and you should really be checking against limit Since right now you ignore limit
McMahone
McMahone12mo ago
var temp = x * multiplier;
if (x <= 0)
{
return 0;

}

if ( temp > limit)
{
return x;
}

Console.WriteLine(x);
x = temp;
return RepeatMultiply(x, multiplier, limit);

}
var temp = x * multiplier;
if (x <= 0)
{
return 0;

}

if ( temp > limit)
{
return x;
}

Console.WriteLine(x);
x = temp;
return RepeatMultiply(x, multiplier, limit);

}
`
mtreit
mtreit12mo ago
Yes, that was the idea. Now that I think about it, I would probably use some better variable names and write it something like this:
if (currentValue <= 0)
{
return 0;

}

var newValue = currentValue * multiplier;

if (newValue > limit)
{
return currentValue;
}

Console.WriteLine(newValue);
return RepeatMultiply(newValue, multiplier, limit);
if (currentValue <= 0)
{
return 0;

}

var newValue = currentValue * multiplier;

if (newValue > limit)
{
return currentValue;
}

Console.WriteLine(newValue);
return RepeatMultiply(newValue, multiplier, limit);
Small optimization in there is: don't multiply if you don't have to (like if the value is 0) (rename x to currentValue) But that's just polishing. The code as you wrote it works.
McMahone
McMahone12mo ago
You are right, looks much more tidier and understandable.
Somgör from Human Resources
why not use a loop
mtreit
mtreit12mo ago
I think they are learning recursion.
McMahone
McMahone12mo ago
If I used a loop, would that be iterative? Is there any advantage over the other approach?
mtreit
mtreit12mo ago
Yes, iterative. Recursion is actually usually worse if there is a straightforward iterative solution. It's slower and dangerous in languages like c# that don't have tail call optimizations, because if you recurse too deeply you can stack overflow
McMahone
McMahone12mo ago
Thank you @mtreit
Accord
Accord12mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.