IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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 :

Problème de précision ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Par défaut Problème de précision ?
    Bonjour,

    Je dois chercher dans un triangles équilatéral de 273 de côté, les points à l'intérieur du triangle pour lesquels la distance aux trois sommets de celui-ci sont des valeurs entières.

    Voici les résultats :

    http://img225.imageshack.us/content_...ng&via=mupload

    Le problème est le suivant. Une fois trouvé les valeurs des coordonnées donnant le résultat attendu, je reinjecte ces coordonnées dans les équations de cercles afin de vérifier que j'ai bien calculé ce qu'il fallait. Cependant, comme vous pourrez le remarquer sur l'image ci dessus. Pour un des résultats, je ne récupère pas une valeur entière.

    Je voulais savoir si cela venait d'un problème de précision ou si cela pourrait venir de ma fonction qui détermine si une valeur est entière ( unsigned int isInteger( float x ) ) ?

    Quelques explications supplémentaires pour s'imprégner du code :

    Les résultats sont organisés par groupe de 3 lignes
    ligne 1 : (x,y) les coordonnées du point qui donne des distances entières aux trois sommets.
    lignes 2 : Les distances en question aux 3 sommets
    lignes 3 : Vérification des valeurs trouvées. J...'ai réinjécté le couple (x,y) dans les equations de cercles afin de voir que mes calculs étaient justes.

    En effet je retrouve bien les valeurs déterminées par l'algorithme mais pas complétement pour une des valeurs.

    J'ai pris 3 points A(0,0) B(273/2, 273*V3/2) C(0,273). Et j'ai déduis les équations de cercles de centre A, B, C.

    Concrètement ce que je fais :

    Je fais varier les rayons des cercles de centre A et B par pas de 1. Donc double for imbriquées.
    Ensuite je regarde s'il y a intersection entre les cercles par un tas de calculs ennuyeux.
    Je renvois la solution qui appartient au triangle équilatéral.
    Du point d'intersection trouvé, je calcul la distance au point C.
    Si cette valeur est entière je retourne le résultat sinon je continue.
    Pour obtenir les autre résultats, il suffit de faire des symétries... Mais cela donnerait de toutes façons des combinaisons différentes des valeurs déjà trouvées.

    Voici le code source :

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
     
    float checkRa( float x, float y )
    {
        return sqrt( x*x + y*y );
    }
     
    float checkRb( float x, float y )
    {
        return sqrt( (x-273/2)*(x-273/2) + (y-273*sqrt(3)/2)*(y-273*sqrt(3)/2) );
    }
     
    float checkRc ( float x, float y )
    {
        return sqrt( (x-273)*(x-273) + y*y );
    }
     
    float DELTA( float A, float B, float C )
    {
        return sqrt( B*B-4*A*C );
    }
     
    float x( float A, float B, float D )
    {
        return (-B+D)/(2*A);
    }
     
    float y( float N, float x, float xa, float ya, float xb, float yb )
    {
        return N-x*(xb-xa)/(yb-ya);
    }
     
    float N( float ra, float rb, float xa, float xb, float ya, float yb )
    {
        return (ra*ra-rb*rb-xa*xa+xb*xb-ya*ya+yb*yb)/(2*(yb-ya));
    }
     
    float A( float xa, float ya, float xb, float yb )
    {
        return (xb-xa)*(xb-xa)/((yb-ya)*(yb-ya)) + 1;
    }
     
    float B( float N, float xa, float ya, float xb, float yb )
    {
        return 2*yb*(xb-xa)/(yb-xa) - 2*N*(xb-xa)/(yb-xa) - 2*xb;
    }
     
    float C( float xb, float yb, float N, float rb )
    {
        return xb*xb+yb*yb+N*N-rb*rb-2*yb*N;
    }
     
    float distanceAB( float xa, float ya, float xb, float yb )
    {
        return sqrt( (xb-xa)*(xb-xa)+(yb-ya)*(yb-ya) );
    }
     
    float isInteger( float x )
    {
        if ( x-(int)x == 0 )
        {
            return 1;
        }
     
        else return 0;
    }
     
    int main (void)
    {
        float xa = 0;
        float ya = 0;
        float xb = 273/2;
        float yb = 273*sqrt(3)/2;
        float xc = 273;
        float yc = 0;
     
        size_t i,j;
        for ( i=0 ; i<=273 ; i++ )
        {
            for ( j=0 ; j<=273 ; j++ )
            {
                float _N = N( i, j, xa, xb, ya, yb);
                float _A = A( xa, ya, xb, yb );
                float _B = B( _N, xa, ya, xb, yb );
                float _C = C( xb, yb, _N, j );
     
                if ( DELTA( _A, _B, _C ) > 0 )
                {
                    float _x = x( _A, _B, DELTA( _A, _B, _C ) );
                    float _y = y( _N, _x, xa, ya, xb, yb );
     
                    if ( isInteger( distanceAB( _x, _y, xc, yc ) ) == 1 )
                    {
                        printf("\n x=%.20f, y=%.20f\n %d - %d - %f\n %.20f - %.20f - %.20f\n ", _x, _y, i, j, distanceAB( _x, _y, xc, yc ), checkRa(_x, _y), checkRb(_x, _y), checkRc(_x, _y) );
                    }
                }
            }
        }
     
        return 0;
    }
    Merci d'avance pour vos lumières.

  2. #2
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Qia,

    En utilisant des réels (float), tous les calculs sont des approximations (entre 2 réels quelconques différents, il y a une infinité de réels ...).

    Tu peux améliorer un peu en utilisant des double, mais ce problème est irréductible.

  3. #3
    Membre éclairé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Par défaut
    Ok, du coup je sors du cadre du topic mais sait-on jamais... Auriez vous une autre idée pour résoudre se problème puisque celui-ce n'est pas viable...

  4. #4
    Membre expérimenté Avatar de quetzacoatl
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 168
    Par défaut
    Bonsoir,

    Ce que vous pouvez faire c'est faire une structure nombre avec un champ int mantisse et un autre champ int exposant, si vos nombres n'ont pas trop de décimales, ca pourrait peut-être convenir

  5. #5
    Membre éclairé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Par défaut
    Selon droggo il n'y a pas de moyen...
    Je parlais de la méthode pour déterminer les valeurs.

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par darkwall_37 Voir le message
    Selon droggo il n'y a pas de moyen...
    Je parlais de la méthode pour déterminer les valeurs.
    Ce problème est récurrent et on le retrouve dans d'autres domaines. Par exemple, dans les transactions bancaires, il est inconcevable d'avoir une erreur due à l'arrondi.
    Il existe une librairie qui calcule les nombres décimaux en précision absolue. Elle travaille en fait comme dans le type decimal(n, m). Chaque chiffre est écrit sur une position et les calculs se font comme au primaire, chiffre par chiffre, colonne par colonne.

    Toi, ton problème est que tu as des fractions et des racines. Ben tu peux te lancer à créer une librairie pour gérer les fractions. Une structure "s_frac" contenant un numerateur, un denominateur. Puis tu codes les opérations "addition", "soustraction", "multiplication" et "division" etc.

    Et tu fais de même avec les racines...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. Problème de précision dans une requête
    Par Le Pharaon dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 09/08/2006, 14h16
  2. Réponses: 5
    Dernier message: 11/05/2006, 08h51
  3. Problème de précision avec FloatToStr
    Par Clorish dans le forum Langage
    Réponses: 9
    Dernier message: 06/12/2005, 15h38
  4. Réponses: 4
    Dernier message: 26/10/2005, 20h38
  5. [FLASH MX] Problème de "précision"
    Par will-scs dans le forum Flash
    Réponses: 2
    Dernier message: 03/07/2005, 00h31

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