Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

flottant multiple de 90


Sujet :

C++

  1. #1
    Membre régulier
    flottant multiple de 90
    Bonjour,

    J'ai un flottant qui contient un angle.

    Si cet angle est proche d'un multiple de 90.0, j'ai des risques de division par zéro qui vienne perturber le bon fonctionnement de mon programme.

    Ce code très moche me permet de ne pas rencontrer de problème :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    if (this->angleHorizontal == (float16)(sint32)this->angleHorizontal) this->angleHorizontal += 0.001;


    Ce code me permet de ne pas tomber sur un nombre "entier" exactement.

    J'aimerais faire un code équivalent, qui n'ai pas de test reel==reel et qui ne modifie que les multiple de 90. Le test revient toutes les 16 ms.

    Pouvez-vous me guider ?

    Merci.

  2. #2
    Membre expert
    effectivement le test réel == réel c'est pas un bon plan, je te propose ça :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // n le nombre dont on a besoin qu'il ne s'approche pas d'un multiple de 90
    double n = 90.0001;
    // MODULO pour calculer le modulo 90
    const double MODULO = 90.0;
    // EPSILON pour la comparaison de flottants, à choisir selon son besoin
    const double EPSILON = 0.001;
     
    // on calcul le reste de la division de n par m
    double reste = fmod(n, MODULO);
     
    // si reste s'approche de 0 ou si reste s'approche de 90 (strictement et à EPSILON près)
    // on ajoute EPSILON à n pour s'écarter de la valeur critique
    if( reste < EPSILON || reste > MODULO - EPSILON )
    	n += EPSILON;


    c'est pas de première qualité, ça n'éloigne pas tant que ça de la valeur critique (si on remet en entrée la valeur de sortie, ça peut ajouter à nouveau EPSILON), mais on tombe pas sur 90.

    ps: ce test pose moins de problème
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if( reste < EPSILON )
    	n += EPSILON;
    if( reste > MODULO - EPSILON )
    	n -= EPSILON;

  3. #3
    Membre régulier
    Je viens de décortiquer ton code, faire des tests et il fonctionne selon mes attentes. Je ne connaissais pas la fonction fmod().

    Merci beaucoup.

  4. #4
    Membre régulier
    Voici le résultat final :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
        float angle = 90.001;
     
        const float EPSILON = 0.001;
        const float MODULO = 90.0;
     
        float reste = fmod(angle, MODULO);
     
        if (angle >= 0.0f) // Angle positif ou nul
        {
            if (reste < EPSILON) // 0+
            {
                angle += EPSILON;
            }
            else if (reste > MODULO - EPSILON) // 90-
            {
                angle -= EPSILON;
            }
        }
        else // Angle negatif
        {
            if (reste > -EPSILON) // 0-
            {
                angle -= EPSILON;
            }
            else if (reste > -MODULO + EPSILON) // (-90)+
            {
                angle += EPSILON;
            }
        }


    A bientôt.

###raw>template_hook.ano_emploi###