Синусы обычно считает все-таки процессор. В отдельных случаях (softfloat для армов и compile-time-константность) они считаются и софтверно, но это то, с чем большинство людей не сталкивается.
> Ну и как ты это собираешься использовать?
Если x имеет небольшое значение, sin x можно приравнять к x.
> Или просто взблеснуть решил?
Да. Получилось?
> Методов-то всего ничего: либо ряды, либо Тейлор.
если обрезать тейлора, то полученный многочлен будет ОЧЕНЬ хорош вблизи нуля, а дальше хуже и хуже.
На каком-нибудь отрезке, скажем [-pi/2, pi] можно подобрать многочлен той же степени что и тот отрезок тейлора, но он будет лучше приближать по всему отрезку (хотя конечно около нуля -- хуже). Поэтому там не тейлор, а вручную подобранный многочлен. (плюс учет периодичности).
Помнится, в нашем 10м классе физмат лицея один гений отжёг на физике: раз синус малого угла примерно равен значению самого угла, то положим sin(4)=4. Реально было ;) Урок был сорван.
Вот мой учебный код. Использует рекурсию, не использует многочлен равномерного приближения.
sin.c
/*****************************************************************
sin(x) evaluation routine
If x > EPS value, the following recursion is used
sin(x) = 3*sin(x/3)-4*sin(x/3)^3.
When x < EPS, a part of Taylor series for sinus is employed
sin(x) = x + O(x^3), O<=1/6
EPS is chosen so, that EPS^3/6 <= macheps = 5.551115e-17 (for double)
Если x > EPS, выполняется рекурсивный спуск по формуле
sin(x) = 3*sin(x/3)-4*sin(x/3)^3.
Когда x < EPS, используется отрезок ряда Тейлора
sin(x) = x + O(x^3), O<=1/6
EPS выбирается так, что его остаток не превосходит маш. точности,
macheps = 5.551115e-17 (для чисел двойной точности)
*****************************************************************/
#include<stdio.h>
#include <stdlib.h>
const double EPS = 1.0e-6;
double fabs (double x) {return (x>0? x: -x);}
double
p_sin3x(double x)
{
return x*(3.0 - 4.0*x*x);
}
double
rsin(double x)
{
if(fabs(x)>EPS)
return p_sin3x(rsin(x / 3.0));
else
return x * (1.0 + (-1.0 + 1.0/20.0 * x * x) * x * x/6.0);
}
int
main(int argc, char* argv[])
{
if(argc>1)
printf("%.17f\n", rsin(atof(argv[1])));
else
printf("Usage: %s x\n", argv[0]);
return 0;
}
Собирать
gcc -o sin sin.c
Недостатки: не приводит вначале аргумент к отрезку [0;2Pi], однако работает и вне его, но не столь эффективно.
Ну раз ты такой кретин, можешь его не читать. Смысл сводится к тому, что есть разные способы счета без использования сопроцессора. В сопроцессорах обычно многочлены равномерных приближений, как я уже сказал.
Раз ты такой, должен бы знать, что чаще всего вообще таблицами обходятся. А то и в целых числах синусы считать умудряются. И да, читать мне его нифик н сдалось. И вообще, offtopic.