Reputation: 3071
In the code below it should multiply 2 numbers. It works for 3 and less than 3 digits numbers but when I give numbers with 4 digits or bigger it gives runtime error: stackoverflow exception was unhandled
. I've commented where the problem is. I thought the problem is for defining variables in int
and changed them in long but the problem still exists. Where is the mistake?
edited: now,whats do you think about the problem?it doesnt do anything
public long Prod2(long u, long v)
{
var numbers = textBox7.Text.Split(',').Select(p => long.Parse(p)).ToArray();
int n = Math.Max((int)Math.Floor(Math.Log10(u) + 1),(int)Math.Floor(Math.Log10(v) + 1));
int threshold = 3;
if (u == 0 || v == 0)
{
return 0;
}
else if (n <= threshold)
{
return u * v;
}
else
{
int m = (int)Math.Ceiling(n / 2.0);
int x = (int)(u / Math.Pow(10, m));
int y = (int)(u % Math.Pow(10, m));
int w = (int)(u / Math.Pow(10, m));
int z = (int)(v % Math.Pow(10, m));
long r = Prod2(x + y, w + z);
long p = Prod2(x, w);
long q = Prod2(y, z);
return p * (long)Math.Pow(10, 2 * m) + (r - p - q) * (long)Math.Pow(10, m) + q;
long result = Prod2(numbers[0], numbers[1]);
textBox1.Text = result.ToString();
}
}
Upvotes: 1
Views: 3029
Reputation: 18363
EDIT: I've completely translated the algorithm described in the book for you:
public long Prod2(long u, long v)
{
int n = Math.Max((int)Math.Floor(Math.Log10(u) + 1), (int)Math.Floor(Math.Log10(v) + 1));
int threshold = 3;
if(u == 0 || v == 0)
{
return 0;
}
else if(n <= threshold)
{
return u * v;
}
else
{
int m = (int)Math.Ceiling(n / 2.0);
int x = (int)(u / Math.Pow(10, m));
int y = (int)(u % Math.Pow(10, m));
int w = (int)(u / Math.Pow(10, m));
int z = (int)(v % Math.Pow(10, m));
long r = Prod2(x + y, w + z);
long p = Prod2(x, w);
long q = Prod2(y, z);
return p * (long)Math.Pow(10, 2 * m) + (r - p - q) * (long)Math.Pow(10, m) + q;
}
}
To get the right result, you'd call this method from some other method like this:
void Main()
{
// Call the method and store the result in variable 'r'.
long r = Prod2(1234, 5678);
Console.WriteLine(r);
/////////////////////////////////
//
// OR - In your case read from textBox7 and then store the result in textBox1
//
/////////////////////////////////
var numbers = textBox7.Text.Split(',').Select(p => long.Parse(p)).ToArray();
long result = prod2(numbers[0], numbers[1]);
textBox1.Text = result.ToString();
}
So in your event handler, for example for button1
, you'd do this to make the call:
public void button1_Click()
{
var numbers = textBox7.Text.Split(',').Select(p => long.Parse(p)).ToArray();
long result = prod2(numbers[0], numbers[1]);
textBox1.Text = result.ToString();
}
Don't modify the Prod2
that I have, and just paste it with your code. This way, Prod2 does the calculation and then your button1_Click
controls the input and what to do with the output.
Upvotes: 2
Reputation: 35287
You are getting into an infinite recursive loop at this point
long result = bigzarb(x, w) * Math.Pow(10, m) + (bigzarb(x, w) + bigzarb(w, y)) * Math.Pow(10, m) + bigzarb(y, z);///here
textBox1.Text = result.ToString();
I notice this line is executed only when intn > 3
, so perhaps you have a logic bug there?
Update: After reading your comments I can see that this test is intended to say "if the length of this string is <= 3 then..." when in fact as written it is actually saying "if the VALUE of this converted string is <= 3 then..."
Upvotes: 3
Reputation: 1781
you are getting "StackoverFlow" for the Recursive call. its better to mold the holes found in the code. I suggest you to change the logic.
static int callStack = 0;
public double bigzarb(long u, long v)
{
callStack++;
............
............
Upvotes: 0
Reputation: 89765
Pow method returns double, so I think your x, y, z, w, and z should be declared as double as well.
Upvotes: 0
Reputation: 75872
In a nutshell you have a potential (varying on input) case of:
function bigzarb()
{
bigzarb()
}
so long as the numbers in textBox7
are > 3, i.e. an unclosed recursion loop, which will inevitably become a stackoverflow.
Put a breakpoint on the line in question and you'll quickly see the problem. Without knowing what your method does (I don't recognise the algorithm) I can't help much about cleaning it up, but the first step might be to have a get out clause to return from the function conditionally. However, I also see you overwriting the input arguments u
and v
before they get used so perhaps you've made a mistake in the algo?
Upvotes: 2