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

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    avril 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2007
    Messages : 72
    Points : 79
    Points
    79

    Par défaut 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

    Profil pro
    Inscrit en
    février 2006
    Messages
    2 003
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : février 2006
    Messages : 2 003
    Points : 3 180
    Points
    3 180

    Par défaut

    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
    Profil pro
    Inscrit en
    avril 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2007
    Messages : 72
    Points : 79
    Points
    79

    Par défaut

    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
    Profil pro
    Inscrit en
    avril 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2007
    Messages : 72
    Points : 79
    Points
    79

    Par défaut

    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.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 87
    Dernier message: 06/07/2011, 16h33
  2. tableau flottant multiplication de cellule
    Par raphl dans le forum Excel
    Réponses: 1
    Dernier message: 22/06/2011, 23h50
  3. Multiplication de flottants issues de texbox
    Par stefsas dans le forum ASP.NET
    Réponses: 3
    Dernier message: 29/06/2010, 10h55
  4. [Kylix] Probleme de nombre flottant!!
    Par yopziggy dans le forum EDI
    Réponses: 5
    Dernier message: 02/05/2002, 11h13
  5. Réponses: 6
    Dernier message: 25/03/2002, 22h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo