История изменений
Исправление cdslow, (текущая версия) :
Ну, вот тебе модуль поточнее, только я уверен, что это будет в разы медленнее, чем один раз использовать double:
#include <stdio.h>
#include <math.h>
float fmod_pi(float a)
{
float const PI_A = M_PI;
float const PI_B = M_PI - PI_A;
int pi_e;
int e;
float pi_a, pi_b;
frexpf(PI_A, &pi_e);
frexpf(a, &e);
e -= pi_e;
pi_a = ldexpf(PI_A, e);
pi_b = ldexpf(PI_B, e);
while(a > PI_A)
{
if(a > pi_a)
{
a -= pi_a;
a -= pi_b;
}
else
{
pi_a /= 2;
pi_b /= 2;
}
}
return a;
}
int main(void)
{
float t = 1221231.f;
fprintf(stderr, "double: %.20lf\n", fmod(t, M_PI));
fprintf(stderr, "double/float: %.20lf\n", fmod(t, (float)M_PI));
fprintf(stderr, "float: %.20lf\n", fmodf(t, M_PI));
fprintf(stderr, "fmod_pi: %.20lf\n", fmod_pi(t));
fprintf(stderr, "t: %.20lf\n", t);
return 0;
}
/*
double: 2.82936269331181122766
double/float: 2.79537892341613769531
float: 2.79537892341613769531
fmod_pi: 2.82776045799255371094
t: 1221231.00000000000000000000
*/
Исходная версия cdslow, :
Ну, вот тебе модуль поточнее, только я уверен, что это будет в разы медленнее, чем один раз использовать double:
#include <stdio.h>
#include <math.h>
float fmod_pi(float a)
{
float const PI_A = M_PI;
float const PI_B = M_PI - PI_A;
int pi_e;
int e;
float pi_a, pi_b;
frexpf(PI_A, &pi_e);
frexpf(a, &e);
e -= pi_e;
pi_a = ldexpf(PI_A, e);
pi_b = ldexpf(PI_B, e);
while(a > PI_A)
{
if(a > pi_a)
{
a -= pi_a;
a -= pi_b;
}
else
{
pi_a /= 2;
pi_b /= 2;
}
}
return a;
}
int main(void)
{
float t = 1221231.f;
fprintf(stderr, "%.20lf\n", fmod(t, M_PI));
fprintf(stderr, "%.20lf\n", fmod(t, (float)M_PI));
fprintf(stderr, "%.20lf\n", fmodf(t, M_PI));
fprintf(stderr, "%.20lf\n", fmod_pi(t));
return 0;
}
/*
double: 2.82936269331181122766
double/float: 2.79537892341613769531
float: 2.79537892341613769531
fmod_pi: 2.82776045799255371094
t: 1221231.00000000000000000000
*/