Создание пользовательской функции Sin () в Java - PullRequest
2 голосов
/ 27 октября 2008

Мне нужно создать функцию sin с нуля в моем классе Comp Sci, и я уже близко к решению. Однако у меня все еще есть несколько проблем. Если я введу значение .5PI или меньше, это будет работать, но в противном случае я получу неправильный результат Вот код, который у меня есть:

double i=1;
double sinSoFar = 0;
int term = 1;
while(i >= .000001)
{
    i = pow(-1, term + 1) * pow(sinOf, 2*term-1) / factorial(2*term-1);
    sinSoFar=sinSoFar + i;
    term++;
}

Ответы [ 3 ]

5 голосов
/ 27 октября 2008

Как указал Федерико, проблема, вероятно, заключается в вашем факториале () или pow (). Я выполнил тест, который работал нормально, заменив ваши функции функцией pow (), предоставленной в классе Math, и этим factorial ():

public static long factorial(long n) {
        if      (n <  0) throw new RuntimeException("Underflow error in factorial");
        else if (n > 20) throw new RuntimeException("Overflow error in factorial");
        else if (n == 0) return 1;
        else             return n * factorial(n-1);
} 
3 голосов
/ 27 октября 2008

Несколько советов:

  • Начните с члена = 0. Каноническое расширение Маклаурина также делает
  • вычисляет полномочия и факториал во время цикла (то есть обновляя их на каждом шаге). Возможно, проблема в функции pow () или factorial ().

EDIT. Предложение: как только вы вычислили k-й член, вы можете вычислить (k + 1) -й член следующим образом:

  • Умножение на (-1)
  • Умножение на sinOf ^ 2
  • Деление на (2k + 2) (2k + 3)

Таким образом, вы можете полностью избежать вычисления степеней и факториалов.

0 голосов
/ 27 октября 2008

Что касается значений за пределами 0 - 1 / 2PI, все они могут быть вычислены из значений внутри диапазона.

// First, normalize argument angle (ang) to -PI to PI, 
// by adding/subtracting 2*PI until it's within range
if ( ang > 1/2PI ) {
    sin = sin ( PI - ang );
}
else if ( ang < 0 ) {
    sin = -1 * sin( -1 * ang );
}
else {
    // your original code
}
...