Arash
Arash

Reputation: 3071

stackoverflow exception was unhandled

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

Answers (5)

TheCloudlessSky
TheCloudlessSky

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

Ed Guiness
Ed Guiness

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

Mohanavel
Mohanavel

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

Vlad Bezden
Vlad Bezden

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

annakata
annakata

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

Related Questions