Странные значения в методе рекурсии в C # - PullRequest
0 голосов
/ 22 мая 2018

В качестве упражнения один из наших учеников должен выполнить рекурсивную функцию синуса.(Используя обобщенную дробную дробь) Я попытался помочь ему, выполнив значительную долю кодирования в сравнении, и теперь столкнулся с проблемой, которую не понимаю.

У меня есть функция, которая работает.Чего я не понимаю, так это того, почему мои первые три или четыре попытки потерпели неудачу.Я пытался пошагово отлаживать эту вещь, но я не могу точно определить свою ошибку.Я действительно хотел бы знать, что мне не хватает.

Осторожно, потому что код не так красив, как мог бы быть.Это быстрое и грязное подтверждение концепции, которую я написал (много раз) за 5 минут.

Вот код, который не работает:

// number = the angle in radian

static double sinus(double number, double exp = 1, bool mustAdd = false, double precision = 0.000001)
{
    if (number < 0) throw new ArgumentException("sinus");
    if (number == 0) return 0;
    double result = ((Math.Pow(number, exp)) / factorial(exp));
    Console.WriteLine(result);

    if (result > precision)
    {
        if (mustAdd)
            return result += sinus(number, exp + 2, !mustAdd);
        else
            return result -= sinus(number, exp + 2, !mustAdd);
    }
    else
        return result;
}

Я печатаю каждую итерацию спромежуточные значения, чтобы убедиться, что все работает соответственно.Значения верны.

Вот рабочий код, который я придумал (Да, он тоже грязный):

static double Altersinus(double number, double exp = 1, bool mustAdd = true, double precision = 0.000001, double result = 0)
{
    if (number < 0) throw new ArgumentException("altersinus");
    if (number == 0) return 0;

    double tmp = ((Math.Pow(number, exp)) / factorial(exp));
    Console.WriteLine(tmp);

    if (tmp > precision)
    {
        if (mustAdd)
            result += tmp;
        else
            result -= tmp;
        result = Altersinus(number, exp + 2, !mustAdd, precision, result);

    }

    return result;
}

Я также пишу промежуточные значения, и они точно такие жекак функция, которая не работает.

Опять же, я действительно не ищу решение, нет спешки.Я просто пытаюсь понять, почему это не работает.Я хотел бы знать, что технически отличается между моими двумя методами.

Любая идея будет высоко ценится.

Cheers.

РЕДАКТИРОВАТЬ

Я пробовал обе функции со значением 3.14159265358979 (примерно 180 градусов)

Обе функции печатают промежуточные значения этих тезисов:

3.14159265358979
5.16771278004997
2.55016403987735
0.599264529320792
0.0821458866111282
0.00737043094571435
0.000466302805767612
2.19153534478302E-05
7.95205400147551E-07

Метод, который не работает, возвращает -3.90268777359824 какрезультат, который полностью ложен.

Тот, который работает, возвращает -7.72785889430639E-07.Что примерно соответствует нулю.

1 Ответ

0 голосов
/ 23 мая 2018

Я понял это.

Давайте заменим исчисление на 'nx', где x - экспонент, а n - число.

В функции, которая работает, я на самом деле так:

Sine(n)=n1/1! - n3/3! + n5/5! - nx/x!...

Но тот, который не работает, немного отличается.Он делает что-то еще:

Sine(n)=n1/1! - (n3/3! + (n5/5! - (nx/x!...)))

Ключом здесь являются круглые скобки.Это влияет на исчисление большое время, из-за вычитания.

Если бы было только сложение, это не вызвало бы никаких проблем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...