LINUX.ORG.RU

История изменений

Исправление 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
*/