исключение stackoverflow было обработано - PullRequest
1 голос
/ 20 декабря 2010

В приведенном ниже коде следует умножить 2 числа. Он работает для 3-х и менее 3-х значных чисел, но когда я даю номера с 4-х и более цифрами, это дает ошибку времени выполнения: stackoverflow exception was unhandled Я прокомментировал, где проблема. Я думал, что проблема заключается в определении переменных в int и менял их долго, но проблема все еще существует. Где ошибка?

изм: Теперь, что вы думаете о проблеме? Она ничего не делает

        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();
        }
    }

Ответы [ 5 ]

3 голосов
/ 20 декабря 2010

В этот момент вы попадаете в бесконечный рекурсивный цикл

 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();

Я заметил, что эта строка выполняется только при intn > 3, так что, возможно, у вас есть логическая ошибка там? Обновление: После прочтения ваших комментариев я вижу, что этот тест предназначен для того, чтобы сказать «если длина этой строки <= 3, то ...», хотя на самом деле, как написано, он фактически говорит «еслиЗНАЧЕНИЕ этой преобразованной строки равно <= 3 then ... "</p>

2 голосов
/ 20 декабря 2010

РЕДАКТИРОВАТЬ: я полностью перевел алгоритм, описанный в книге для вас:

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;
    }
}

Чтобы получить правильный результат, вы бы вызвали этот метод из какого-то другого методанапример:

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();
}

Итак, в вашем обработчике событий, например, для button1, вы должны сделать это , чтобы сделать вызов:

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();
}

Не изменяйте Prod2, который у меня есть, а просто вставьте его вместе с вашим кодом.Таким образом, Prod2 выполняет вычисления, а затем ваш button1_Click контролирует вход и что делать с выходом .

2 голосов
/ 20 декабря 2010

В двух словах у вас есть потенциальный (варьирующийся от ввода) случай:

function bigzarb()
{
    bigzarb()
}

, пока числа в textBox7> 3, то есть незамкнутый цикл рекурсии, который неизбежно станетпереполнение стека.

Поставьте точку останова на рассматриваемой строке, и вы быстро увидите проблему.Не зная, что делает ваш метод (я не распознаю алгоритм), я не могу помочь в его очистке, но первым шагом может быть предложение get out для условного возврата из функции.Тем не менее, я также вижу, как вы перезаписываете входные аргументы u и v, прежде чем они привыкнут, так что, возможно, вы допустили ошибку в алгоритме?

0 голосов
/ 20 декабря 2010

вы получаете «StackoverFlow» для рекурсивного вызова. лучше сформировать отверстия, найденные в коде. Я предлагаю вам изменить логику.

static int callStack = 0;

    public double bigzarb(long u, long v)
    {
        callStack++;
         ............
         ............
0 голосов
/ 20 декабря 2010

Метод Pow возвращает double, поэтому я думаю, что ваши x, y, z, w и z также должны быть объявлены как double.

...