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++Builder Discussion :

C++Builder fait une erreur de calcul


Sujet :

C++Builder

  1. #1
    Membre confirmé
    Homme Profil pro
    Consultant technique
    Inscrit en
    Juillet 2002
    Messages
    519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2002
    Messages : 519
    Points : 523
    Points
    523
    Par défaut C++Builder fait une erreur de calcul
    Voila mon problème.
    J'ai une variable de type float qui contient une valeur quelconque entière ou avec .5 (ex : 0, 0.5, 1, 1.5, 2, ...)
    je veux en prendre 20%. Donc je multiplie par 20 et divise par 100.
    La multiplication ne pose aucun problème mais pour la division, il ne donne pas le bon résultat. Par exemple :
    Normalement : 1 * 20 / 100 = 0.2
    C++Builder : 1 * 20 / 100 = 0.200000002980232
    C++Builder : 1 * 0.2 = 0.2
    Seulement, le pourcentage est défini par l'utilisateur et je ne sais donc pas d'avance quel sera ce chiffre. Si je calcule le pourcentage avant, ca fait toujours la même chose. L'utilisateur entre le pourcentage dans un CurrencyEdit de la RXlib. C'est donc un long double alors que je n'ai besoin que d'un int. De plus, j'ai beaucoup d'opération dans mon programme dont des divisions.

    Que faire? D'où vient mon problème?
    merci

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 163
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 163
    Points : 1 148
    Points
    1 148
    Par défaut
    Essaye de cocher la case "Corriger le défaut Pentium FDIV" dans l'onglet "Options avancées du compilateur" dans la boite d'options de ton projet.....
    Neilos

  3. #3
    Membre habitué Avatar de monnoliv
    Homme Profil pro
    Opticien-ébéniste: lunettes de WC
    Inscrit en
    Août 2003
    Messages
    139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Opticien-ébéniste: lunettes de WC

    Informations forums :
    Inscription : Août 2003
    Messages : 139
    Points : 195
    Points
    195
    Par défaut
    Essaie plutôt de travailler avec des entiers que tu convertiras en tout dernier lieu.
    Exemple: tu codes ta valeur dans un entier en la multipliant par 1000, soit dans ton exemple 0.5, 1.0, 1.5, 2,... sont codés 500, 1000, 1500, 2000. Ensuite tu peux prendre x/100 (avec x entier) de chaque valeur et le résultat sera un entier. A la fin tu convertis ( fX = (double) X).

    D'où vient mon problème?
    L'encodage des nombres en virgule flottante dans un ordinateur est fini, donc forcément l'ordinateur ne peut représenter tous les nombres de manière exacte.
    Bàt,
    IoT CC3200, ESP8266
    8051, ARM Cortex-M (forever)/Cortex A (TI, Silabs, NXP), FPGA, Bare Metal Raspberry-PI programming
    VHDL-ALTERA-XILINX

  4. #4
    Membre confirmé
    Homme Profil pro
    Consultant technique
    Inscrit en
    Juillet 2002
    Messages
    519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2002
    Messages : 519
    Points : 523
    Points
    523
    Par défaut
    J'ai déja essayé de cocher la case "Corriger le défaut Pentium FDIV" et ca fait rien.

    Pour la 2ème solution, ca marche pas non plus. Ca donne la même chose.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Travailleur = Pop * CurrencyEdit2->Value / 100;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Pourcent = Pop * 1000;
    Travailleur = Pourcent * CurrencyEdit2->Value / 100;
    Travailleur = Travailleur / 1000;
    Donne la même chose. C'est un résultat que l'utilisateur voit et doit donc remettre "/ 1000"

  5. #5
    Membre éprouvé Avatar de Nemerle
    Inscrit en
    Octobre 2003
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 106
    Points : 1 213
    Points
    1 213
    Par défaut
    Essaie à l'envers: dans ton exemple,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     
    float f,g;
    f=1;
    g=100/(f*20);
    et le resultat est 1/g=0.200000000000000000. De mème si f=2,
    1/g=0.40000000000

    Ca a le mérite de simplifier les fractions avant le quotient, mais cela ne règle pas tout...

    mais bon, je ne suis pas développeur... y a surement mieux!
    Nemerle, mathématicopilier de bars, membre du triumvirat du CSTM, 3/4 centre

  6. #6
    CGi
    CGi est déconnecté
    Expert éminent
    Avatar de CGi
    Inscrit en
    Mars 2002
    Messages
    1 026
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 1 026
    Points : 8 311
    Points
    8 311
    Par défaut
    Tu peut travailler avec des double ou même des long double
    tu aura une meilleure précision.

    voir aussi le type TBcd de C++ Builder
    ou la classe bcd du C++
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 70
    Points : 40
    Points
    40
    Par défaut
    reponse : tu n'as pas de probleme

    en effet :
    0.200000002980232 = 0.2 a la louche
    pour toutes tes sorties il faut formater
    par un printf("%7.4f",valeur);
    ce qui te fera disparaitre ces ennuyeux problemes
    sinon apres il faut faire attention dans le programme
    au test ==
    qu'il faut remplacer par abs(a-b)< epsilon
    c'est ainsi
    pas d'autre methhode

  8. #8
    Membre confirmé
    Homme Profil pro
    Consultant technique
    Inscrit en
    Juillet 2002
    Messages
    519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2002
    Messages : 519
    Points : 523
    Points
    523
    Par défaut
    J'ai trouvé la réponse ou plutôt CGi la trouvé. Le composant utilise des double et mes variables des float. En les déclarant double, tout fonctionne.

    Et 20% de 1 fait bien 0.2.

    Merci de m'avoir aidé, j'ai ma solution. C'est une chose à retenir si l'on veut faire des calculs de précisions. Il vaut mieux utiliser des variables de même précisions.

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

Discussions similaires

  1. Excel fait une erreur de calcul !
    Par jlp65 dans le forum Excel
    Réponses: 14
    Dernier message: 05/02/2015, 16h52
  2. Réponses: 1
    Dernier message: 03/05/2007, 12h31
  3. [VC++2005 express] deux projets identiques, l'un me fait une erreur
    Par méphistopheles dans le forum Visual C++
    Réponses: 4
    Dernier message: 16/01/2007, 08h24
  4. fonction qui me fait une erreur
    Par griese dans le forum Langage
    Réponses: 12
    Dernier message: 28/07/2006, 10h46
  5. mktime me fait une erreur
    Par mail1789 dans le forum C++
    Réponses: 2
    Dernier message: 23/08/2005, 10h59

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