C++ résultats erronés avec variables float
Répondre à la discussion
Affichage des résultats 1 à 23 sur 23

C++ résultats erronés avec variables float



  1. #1
    jeremy83

    C++ résultats erronés avec variables float


    ------

    Bonjour,

    J'ai un script c++ qui me pose problème en terme de résultats concernant des valeurs issues de variables de type foat :

    Les résultats sont faux, pas complément à côté de la plaque mais suffisamment faux pour que je ne puisse pas les utiliser.

    Les calculs de font sur des variables de types float parfois avec des valeurs non entières entrées manuellement pour le même calcul.

    J'ai lus différents sujets et j'ai bien compris que l'utilisation de float est a proscrire et qu'il est préférable d'utiliser des nombres entiers.

    Mais je ne veux pas refaire mon script car il est très long, environ 4000 lignes.

    Je crois qu'il est possible d'inclure une lib et j'aimerais savoir si cela serait suffisant et si oui laquelle.

    J'espère aussi que le fait d'utiliser des nombres à virgules non issues de variables directement ne pose pas de problème.

    Si quelqu'un peut me donner sont avis et une référence de lib si c'est possible j'en serais ravie.

    Merci d'avance.

    -----

  2. #2
    umfred

    Re : C++ résultats erronés avec variables float

    ça serait bien d'avoir une idée concrète de ce qui est faux comme résultat pour toi

  3. #3
    pm42

    Re : C++ résultats erronés avec variables float

    Citation Envoyé par umfred Voir le message
    ça serait bien d'avoir une idée concrète de ce qui est faux comme résultat pour toi
    Oui, là on n'a pas d'assez d'informations pour aider. Au passage, on ne sait même pas si le problème est compatible avec l'usage de int puisque le primo-posteur dit " avec des valeurs non entières".

    Un test intéressant serait aussi de remplacer "float" par "double" dans tout le code ce qui se fait facilement avec n'importe quel éditeur et de voir si cela augmente la précision.

  4. #4
    jeremy83

    Re : C++ résultats erronés avec variables float

    Bonjour et merci pour vos réponses.
    Quand je dis que les résultats sont faux cela est très aléatoire.
    Mais je viens de remarquer que ça peux être vraiment erroné par exemple 2 a 3 fois la valeur normal ou l'inverse divisé par 2 ou 3.
    Et effectivement, je reviens sur ce que j'ai dit dans mon premier post, je dois travailler avec des nombre non entiers.

  5. A voir en vidéo sur Futura
  6. #5
    champetre

    Re : C++ résultats erronés avec variables float

    Bonjour,

    Montrer le code minimal qui reproduit le problème est nécessaire, sinon ça va engendrer des frais pour acheter une boule de cristal.

  7. #6
    pm42

    Re : C++ résultats erronés avec variables float

    Citation Envoyé par champetre Voir le message
    Montrer le code minimal qui reproduit le problème est nécessaire, sinon ça va engendrer des frais pour acheter une boule de cristal.
    Oui et il est bizarre de devoir le dire 3 fois parce que pour le moment, la seule info qu'on a est "ça ne marche pas".

    Et la description correspond à de nombreux bugs possibles dont la plupart n'ont rien à voir avec la précision des floats.

  8. #7
    jeremy83

    Re : C++ résultats erronés avec variables float

    Merci pour vos réponses et désolé pour le manque de précision je ne suis pas devant le script.
    Voici le calcul qui ne fonctionne pas :

    V1 = V2 + ((V2*((V3/V4)-1))-V2)-(V2*0.00027);

    Tous les V sont des variables de type float.

    V1 me retourne des valeurs erronées.

    V3 ET V4 sont issus de tableaux de type float.

    L'ensemble tourne dans des boucles while où V2 prend la valeur de V1 sous certaines conditions.

    Je vous donnerez le bout de code si j'arrive a aller devant l'ordinateur.

    Merci à vous.

  9. #8
    pm42

    Re : C++ résultats erronés avec variables float

    Et sans connaître les valeurs des variables et la valeur attendue, tu veux qu’on fasse de la divination ?

  10. #9
    umfred

    Re : C++ résultats erronés avec variables float

    on peut peut-être simplifier le calcul
    ((V2*((V3/V4)-1)-V2) => (V2*((V3/V4)-2))
    V2-V2*0.00027 = V2*(1-0.00027)=0.99973*V2
    donc on peut réécrire V1=V2*(0.99973 -2 + (V3/V4)) = V2*((V3/V4) - 1.00027) si pas d'erreurs dans les parenthèses

  11. #10
    jacknicklaus

    Re : C++ résultats erronés avec variables float

    annulé
    xxxxx
    There are more things in heaven and earth, Horatio, Than are dreamt of in your philosophy.

  12. #11
    jeremy83

    Re : C++ résultats erronés avec variables float

    Bonjour à tous,

    je n'ai pas pu revenir sur le sujet avant aujourd’hui.

    Voici des détails supplémentaires concernant mon problème :

    Plus bas, un morceau du code ou se situe le problème ( avec commentaire //PROBLEME)

    les variables prixvente et prixachat sont dans des fichiers externes (e.h h.h l.h c.h), se sont des tableaux de 18500 lignes de type long double constitués comme suit :

    exemple du fichier l.h (il s'agit de prix en USDT ):

    long double l[]{
    10705 ,
    10720.8 ,
    10732.07 ,
    10736.74 ,
    ...
    ...
    ...
    }

    j'obtiens après vérification des problème de résultats au bout d'un certain temps de fonctionnement du programme.
    À noter que je suis passé de double à long double et le problème survient plus tard désormais !
    C'est comme si à force d'actualiser la valeur de la variables il y avait comme une "saturation" au niveau de celle ci. En float le problème survenait bien plus tôt également.
    Pour info j'ai tenté de travailler avec des variables entières (gros travail sur le code) et cela m'apporte un problème presque similaire au bout d'un certain temps de fonctionnement : idem problème précédant du coup...

    Pour info ce code me permet de calculer mes gains/perte selon des transactions effectuées ou non sur des trades de cryptomonnaies.

    Code:
    #include <iostream>
    #include <fstream>
    #include <stdio.h>
    #include <windows.h>
    
    
    #include "c.h"
    #include "e.h"
    #include "h.h"
    #include "l.h"
    
    long double solde;
    long double soldenew;
    
    /*.................
    
    // autres variables...
    
    .................*/
    
    
    
    int main(){
    	
    	
    mise = 100;
    levier = 25;
    fees =0.00027;
    /*.................
    
    // autres variables...
    
    .................*/
    	
    	
    	
    	
    	
    /*.................
    
    debut du code ne posant pas de problemes.
    
    avec goto achat 1 ou goto vente 1 selon conditions
    
    .................*/
    	
    
    	achat1 :
    	
    if(stepachatmob == 1){
    if(counterdecalage == 0){transactions = 0;  }
    while(counterdecalage < lgtableaux){
    if(e[decalagesamples+counterdecalage+stepdec]*multiachatmob > l[decalagesamples+counterdecalage+stepdec-decachatmob]){
    prixachat = e[decalagesamples+counterdecalage+stepdec+1]; 
    if(newnew == 0) {
    solde = soldenew;  //PROBLEME (calcul plus bas)
    } 
    if(newnew == 1) {
     newnew =0; solde = mise; 
     } 
     
     myfile << decalagesamples+counterdecalage+stepdec+1; 
     myfile << ";A;"; 
     myfile << prixachat; 
     myfile << ";";
     myfile << solde;    //DU COUP : PROBLEME (calcul plus bas)
     myfile << endl; 
    counterdecalage++;
    
    transactions++; derstep = 1;
    if(counterdecalage >= lgtableaux){
        
        goto fin1;
        }
    goto vente1;
    }
    counterdecalage++;
    }
    
    if(counterdecalage >= lgtableaux){
        
        goto fin1;
        }
    
    
    }
    
    
    /*.................
    
    même code : if(stepachatmob == 2){...} à if(stepachatmob == 23){...}
    
    .................*/
    
    
    if(stepachatmob == 24){
      if(counterdecalage == 0){transactions = 0;  }
    while(counterdecalage < lgtableaux){
    if(c[decalagesamples+counterdecalage+stepdec]*multiachatmob < h[decalagesamples+counterdecalage+stepdec-decachatmob]){
    prixachat = e[decalagesamples+counterdecalage+stepdec+1];
     if(newnew == 0) {
    	 solde = soldenew; //PROBLEME (calcul plus bas)
    	 } 
    	 if(newnew == 1) {
    		 newnew =0; solde = mise;
    		 } 
    		 myfile << decalagesamples+counterdecalage+stepdec+1; 
    		 myfile << ";A;"; 
    		 myfile << prixachat; 
    		 myfile << ";";
    		 myfile << solde;  //DU COUP : PROBLEME (calcul plus bas)
    		 myfile << endl;
    counterdecalage++;
    transactions++; derstep = 1;
    if(counterdecalage >= lgtableaux){
        
        goto fin1;
        }
    goto vente1;
    }
    counterdecalage++;
    }
    
    if(counterdecalage >= lgtableaux){
        
        goto fin1;
        }
    
    }
    
    
    vente1 :
    
    if(stepventemob == 1){
    	
    while(counterdecalage < lgtableaux){
    if (l[decalagesamples+counterdecalage+stepdec]/prixachat  <= 1-(prixachat/levier*0.75)/prixachat) {
    	etatliquidation = 1; 
    	}
    if(e[decalagesamples+counterdecalage+stepdec]*multiventemob > l[decalagesamples+counterdecalage+stepdec-decventemob]){
    prixvente = e[decalagesamples+counterdecalage+stepdec+1];
    soldenew=solde+((solde*(prixvente/prixachat)-solde)*levier)-(solde*fees);  //PROBLEME
    if(soldenew < solde *0.25) {
    	etatliquidation = 1; 
    	} 
    	myfile << decalagesamples+counterdecalage+stepdec+1; 
    	myfile << ";V;"; 
    	myfile << prixvente; 
    	myfile << ";";
    	myfile << soldenew; //DU COUP : PROBLEME 
    	myfile << endl;
    	
    counterdecalage++;
    transactions++; derstep = 2;
      if(counterdecalage >= lgtableaux){
        
        goto fin1;
        }
    goto achat1;
    }
    if(counterdecalage >= lgtableaux){
        
        goto fin1;
        }
    counterdecalage++;
    }
    
    }
    
    /*.................
    
    même code : if(stepventemob == 2){...} à if(stepventemob == 23){...}
    
    .................*/
    
    if(stepventemob == 24){
    	
    while(counterdecalage < lgtableaux){
    if (l[decalagesamples+counterdecalage+stepdec]/prixachat  <= 1-(prixachat/levier*0.75)/prixachat) {
    	etatliquidation = 1; 
    	}
    if(c[decalagesamples+counterdecalage+stepdec]*multiventemob > l[decalagesamples+counterdecalage+stepdec-decventemob]){
    prixvente = e[decalagesamples+counterdecalage+stepdec+1];
    soldenew=solde+((solde*(prixvente/prixachat)-solde)*levier)-(solde*fees); //PROBLEME
    if(soldenew < solde *0.25) {
    	etatliquidation = 1; 
    	} 
    	myfile << decalagesamples+counterdecalage+stepdec+1; 
    	myfile << ";V;"; 
    	myfile << prixvente; 
    	myfile << ";";
    	myfile << soldenew; //DU COUP : PROBLEME
    	myfile << endl;
    	
    counterdecalage++;
    transactions++; derstep = 2;
      if(counterdecalage >= lgtableaux){
        
        goto fin1;
        }
    goto achat1;
    }
    if(counterdecalage >= lgtableaux){
        
        goto fin1;
        }
    counterdecalage++;
    }
    
    }
    
    
    /*.................
    
    Fin du code ne posant pas de problemes
    
    .................*/
    
    
    }
    Merci à vous

  13. #12
    Ikhar84
    Animateur Informatique

    Re : C++ résultats erronés avec variables float

    Bonsoir,

    Avant que certains tombent de leur chaise(s)...

    Attention à ton style (indentations, accolades aux bons endroits, déclarations des variables, ...) ton code est illisible à cause de ces libertés que tu prends...
    Attention à la structure à base de goto... label... : ton code devient vite illisible (le GOTO c'est le MAL)...

    Tu n'a pas fourni de jeu de données pour comprendre le problème (même si on sait que le problème vient d'approximations successives dus aux arrondis des calculs et aux limitations dues au codage des nombres en informatique...).

    Voilà (ceci étant dit en toute humilité, mais ton code y gagnerait fortement en lisibilité, et du coup les coups de main serait plus rapide et plus précis...) !

    Edit:
    Au temps pour moi !
    Je n'avais pas vu le résumé du contenu du fichier l.h ... (mais bon sang ! pourquoi ne pas les lire depuis un bête fichier de données au lieu d'utiliser un fichier d'en-têtes).
    Dernière modification par Ikhar84 ; 13/12/2020 à 19h04.
    J'ai glissé Chef !

  14. #13
    jeremy83

    Re : C++ résultats erronés avec variables float

    Le code est long et a été modifié a maintes reprises donc désolé pour le style brouillon.
    Et sinon, une idée ou quelque chose à me proposer ?
    Dans mon cas de figure les goto mon évité d'avoir un code a 100 000 lignes.

  15. #14
    jiherve

    Re : C++ résultats erronés avec variables float

    Bonsoir,
    à tout hasard :https://docs.oracle.com/cd/E19957-01..._goldberg.html
    avec les flottants traités en natif par le processeur les problèmes surgissent lors des additions soustractions car les deux opérandes doivent être exprimés dans le même format , en clair avec le même exposant, on peut alors perdre des décimales!
    voir barrel shifter.
    JR
    Dernière modification par jiherve ; 13/12/2020 à 20h11.
    l'électronique c'est pas du vaudou!

  16. #15
    pm42

    Re : C++ résultats erronés avec variables float

    J'ai regardé très rapidement et il faudrait vraiment voir ce qui se passe soit au débugger, soit avec un cout << bien placé pour noter la dérive d'une variable.

    Mais des trucs comme :

    Code:
    solde*(prixvente/prixachat)-solde)
    dans une boucle peuvent poser problème en effet si prixvente et prixachat ne sont pas très différents, notamment si tu fais des transactions fréquentes.

    Le fait que le problème arrive plus tard quand tu passes en double ou double double va dans ce sens : tu es probablement dans le cas classique du calcul numérique où des petites erreurs d'arrondi sur des calculs en limite de la précision vont se cumuler pour donner à la fin des résultats faux.

    Il faut donc analyser et trouver une autre façon de faire les dits calculs ou augmenter encore la précision avec un outil comme https://gmplib.org

    P.S : ce que dit Ihkar84 est plus que pertinent. A terme, ton code va devenir difficilement maintenable et il existe pratiquement toujours des solutions pour éviter les goto qui ne le rendent pas vraiment plus long, notamment en le décomposant en plus petites fonctions.

  17. #16
    jeremy83

    Re : C++ résultats erronés avec variables float

    Merci pour vos réponses.
    Pour infos j'ai tenté de décomposer le calcul en assignant une variable par opération du calcul mais cela me donne exactement les mêmes résultat ce qui me fait douter sur le fait que le problème vienne seulement de la précision perdu au fil des boucles.

    Pour info, je ne parle pas de petit écarts, quand le calcul commence a être faux je me retrouve avec par exemple un solde qui devrait être à 150 avec un solde a 200 ou l'inverse.

  18. #17
    pm42

    Re : C++ résultats erronés avec variables float

    Citation Envoyé par jeremy83 Voir le message
    Pour infos j'ai tenté de décomposer le calcul en assignant une variable par opération du calcul mais cela me donne exactement les mêmes résultat ce qui me fait douter sur le fait que le problème vienne seulement de la précision perdu au fil des boucles.
    Une autre hypothèse est qu'une seule des opérations (ou 2 ou 3...) soit fausse(s) et que cela plante ton résultat global.

  19. #18
    jeremy83

    Re : C++ résultats erronés avec variables float

    Citation Envoyé par pm42 Voir le message
    Une autre hypothèse est qu'une seule des opérations (ou 2 ou 3...) soit fausse(s) et que cela plante ton résultat global.
    Ce n'est pas la formule que je remet en question ce sont les résultats issues de celle ci : si je reproduit exactement le même calcul avec Excel par exemple tout roule jusqu'à la 5000eme ligne environ et après ça commence à devenir n importe quoi.

  20. #19
    jiherve

    Re : C++ résultats erronés avec variables float

    Re
    lorsque l'on fait des additions/soustractions de quantités infinitésimales il arrive un moment où la somme et l’incrément ne peuvent plus être représentés dans le même format ex:
    1(0x3f800000)et 2^-24(0x33800000) ne peuvent pas partager le même exposant en IEEE 754 32bits donc 1+2^-24 = 1
    expérience a faire à la main ici:https://www.h-schmidt.net/FloatConverter/IEEE754.html
    Le passage en 64 bits ne fait que retarder l'échéance du probleme.
    Pour faire ce genre de calculs il faut un outil de type Mathematica.
    JR
    Dernière modification par jiherve ; 13/12/2020 à 21h04.
    l'électronique c'est pas du vaudou!

  21. #20
    jeremy83

    Re : C++ résultats erronés avec variables float

    Citation Envoyé par pm42 Voir le message
    Une autre hypothèse est qu'une seule des opérations (ou 2 ou 3...) soit fausse(s) et que cela plante ton résultat global.
    Bon... j'ai honte :

    Je viens de trouver le problème qui n'est autre que l'assignation d'une variable avec le même nom (prixachat et prixvente) qui aurait dû être renommé en passant dans la deuxième partie du code...

    avec cet modif tout (pour le moment) est fonctionnel.

    Merci à tous pour votre aide.

  22. #21
    pm42

    Re : C++ résultats erronés avec variables float

    Citation Envoyé par jeremy83 Voir le message
    Je viens de trouver le problème qui n'est autre que l'assignation d'une variable avec le même nom (prixachat et prixvente) qui aurait dû être renommé en passant dans la deuxième partie du code...

    avec cet modif tout (pour le moment) est fonctionnel.
    Tant mieux et bienvenue au club des gens qui ont perdu du temps sur un bug en cherchant la solution ailleurs

  23. #22
    jiherve

    Re : C++ résultats erronés avec variables float

    Re
    pas de raison d'avoir honte tu n'es pas le premier à qui cela arrive et c'est souvent en exposant son problème que l'on trouve tout seul la solution car on se déconnecte et l’oeuil redevient neuf.
    lis tout de même le papier que j'ai fourni en lien cela ne sera pas du temps perdu.
    JR
    l'électronique c'est pas du vaudou!

  24. #23
    jeremy83

    Re : C++ résultats erronés avec variables float

    Merci en tout cas à vous d'avoir pris le temps de répondre à mes questions.
    Mon script peux désormais tourner !

Discussions similaires

  1. Transformer une contraintes en variables 0-1 en contraintes avec des variables réelles
    Par Pianitch dans le forum Mathématiques du supérieur
    Réponses: 6
    Dernier message: 11/08/2017, 11h22
  2. Résultats erronés Fortran 90
    Par ESTERMIQUE dans le forum Physique
    Réponses: 2
    Dernier message: 13/02/2017, 11h25
  3. [Blanc] samsung rsa1ztpe affichages erronés
    Par popaye dans le forum Dépannage
    Réponses: 3
    Dernier message: 27/04/2016, 21h45
  4. [C] - Problèmes de manipulation de variables de type float
    Par jorg1n dans le forum Électronique
    Réponses: 4
    Dernier message: 27/04/2009, 10h12
  5. Courbe d'etalonnage et resultats erronés
    Par invitea4b2b21e dans le forum Chimie
    Réponses: 2
    Dernier message: 18/09/2007, 16h58