К сожалению, я не могу комментировать, поэтому я публикую это как отдельный ответ.
Я думаю, что ответ @ geza правильный, я просто хотел бы добавить несколько деталей.
Согласно исходным кодам GSL, они имеют собственную реализацию тригонометрических функций:
/*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
/* I would have prefered just using the library sin() function.
* But after some experimentation I decided that there was
* no good way to understand the error; library sin() is just a black box.
* So we have to roll our own.
*/
int
gsl_sf_sin_e(double x, gsl_sf_result * result)
{
/* CHECK_POINTER(result) */
{
const double P1 = 7.85398125648498535156e-1;
const double P2 = 3.77489470793079817668e-8;
const double P3 = 2.69515142907905952645e-15;
const double sgn_x = GSL_SIGN(x);
const double abs_x = fabs(x);
if(abs_x < GSL_ROOT4_DBL_EPSILON) {
const double x2 = x*x;
result->val = x * (1.0 - x2/6.0);
result->err = fabs(x*x2*x2 / 100.0);
return GSL_SUCCESS;
}
else {
double sgn_result = sgn_x;
double y = floor(abs_x/(0.25*M_PI));
int octant = y - ldexp(floor(ldexp(y,-3)),3);
int stat_cs;
double z;
if(GSL_IS_ODD(octant)) {
octant += 1;
octant &= 07;
y += 1.0;
}
if(octant > 3) {
octant -= 4;
sgn_result = -sgn_result;
}
z = ((abs_x - y * P1) - y * P2) - y * P3;
if(octant == 0) {
gsl_sf_result sin_cs_result;
const double t = 8.0*fabs(z)/M_PI - 1.0;
stat_cs = cheb_eval_e(&sin_cs, t, &sin_cs_result);
result->val = z * (1.0 + z*z * sin_cs_result.val);
}
else { /* octant == 2 */
gsl_sf_result cos_cs_result;
const double t = 8.0*fabs(z)/M_PI - 1.0;
stat_cs = cheb_eval_e(&cos_cs, t, &cos_cs_result);
result->val = 1.0 - 0.5*z*z * (1.0 - z*z * cos_cs_result.val);
}
result->val *= sgn_result;
if(abs_x > 1.0/GSL_DBL_EPSILON) {
result->err = fabs(result->val);
}
else if(abs_x > 100.0/GSL_SQRT_DBL_EPSILON) {
result->err = 2.0 * abs_x * GSL_DBL_EPSILON * fabs(result->val);
}
else if(abs_x > 0.1/GSL_SQRT_DBL_EPSILON) {
result->err = 2.0 * GSL_SQRT_DBL_EPSILON * fabs(result->val);
}
else {
result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
}
return stat_cs;
}
}
}
Вы должны помнить, что GSL - это библиотека, созданная учеными и для ученых. Поэтому вам нужен способ контролировать свои результаты и их правильность (см. Этот комментарий выше и этот ответ для деталей), скорость в этом случае вторична.
В то же время вы должны помнить, что системные тригонометрические функции были реализованы умными IBM парнями, которые знают, как сделать это быстро (и абсолютно нечитаемо).