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

JavaScript Discussion :

calcul entre réels et résultat faux


Sujet :

JavaScript

  1. #1
    Membre habitué
    Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 182
    Points : 186
    Points
    186
    Par défaut calcul entre réels et résultat faux
    j'ai une erreur de calcul en Javascript incompréhensible :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if (val1<=val2*poids)
     alert('true');
    else
     alert('false');
    val1 est égal à 8.05
    val2 est égal à 3.5
    poids est égal à 2.3
    et il se trouve que 2.3*3.5=8.05 donc cette condition devrait m'afficher 'true'.
    Et ce n'est pas le cas, et j'ai regardé de plus près, il se trouve que javascript me renvoie comme résultat de 2.3*3.5 = 8.0499999999
    Une idée?

  2. #2
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut
    Bonjour,
    sans voir tout le code (fonction entière + initialisation des variables/paramètres) on ne peut pas te dire grand chose

    A+
    Pour tout savoir sur l'utilisation du forum

    En postant votre message, n'oubliez pas les Règles du Club.

  3. #3
    Membre habitué
    Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 182
    Points : 186
    Points
    186
    Par défaut
    Je suis désolé mais ça risque d'être compliqué car ce bout de code fait partie une application Web contenant 10000 ligne de javascript sans compter les pages html et le moment de l'initialisation des variables est perdu au milieu, je peux juste dire que j'ai suivi les variables avec firebug et que jusqu'au bout leur valeur ne change pas, il s'agit juste du calcul. Je voulais juste essayer de trouver quelqu'un ayant eu le cas.

  4. #4
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 637
    Points : 66 661
    Points
    66 661
    Billets dans le blog
    1
    Par défaut
    la desormais classique "virgule flottante"

    une petite recherche sur le forum avec ce terme et aussi "arrondi" te donneront la solution
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  5. #5
    Rédacteur
    Avatar de Arnaud F.
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Août 2005
    Messages
    5 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur COBOL
    Secteur : Finance

    Informations forums :
    Inscription : Août 2005
    Messages : 5 183
    Points : 8 873
    Points
    8 873
    C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère

    Installation de Code::Blocks sous Debian à partir de Nightly Builds

  6. #6
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par loukoum82 Voir le message
    il se trouve que 2.3*3.5=8.05 donc cette condition devrait m'afficher 'true'.
    C'est un souci inhérent à la façon dont sont stockés les nombres décimaux dans un nombre dit "à virgule flottante".

    En javascript, les valuers décimales sont effectivement stockées dans les nombres à virgule flottante 'double précision (ie. codés sur 64 bits), cf. ceci:
    Les nombres en JavaScript sont « des valeurs au format IEEE 754 en double précision 64 bits »
    Et comme le précise wikipédia dans les précautions d'emploi, cette façon de coder les nombres induit parfois des petites pertes de précision qui peuvent (au fur et à mesure de l'enchaînement des calculs) devenir significatives.

    Une solution serait éventuellement de ne pas tester l'égalité exacte, mais un intervalle incluant une imprécision 'acceptable', genre:

    au lieu de:
    faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( Math.abs(i-8.0) < 0.001 )
    EDIT: bon ben je me suis fait multi griller sur ce coup là
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  7. #7
    Membre habitué
    Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 182
    Points : 186
    Points
    186
    Par défaut
    Citation Envoyé par nouknouk Voir le message

    EDIT: bon ben je me suis fait multi griller sur ce coup là
    En fait non, car il n'y a que toi qui réponds vraiment à ma question, sauf que mon problème c'est que je dois être très précis dans mon cas, donc impossible de prévoir une marge d'erreur, d'autant plus que les nombres n'auront pas forcément le même ordre de grandeur selon les cas, (ça peut aller de 2000 à 0.003 par exemple.) mais si il n'y a pas de solution miracle tant pis. Je ferai sans.
    Mais c'est quand même très très étrange...

  8. #8
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    En fait non, car il n'y a que toi qui réponds vraiment à ma question
    Oui et non: comme l'ont précisé Arnaud F. et SpaceFrog ci-dessus, ce genre de problématique est un grand 'classique'. Une recherche sur le forum te donnera certainement beaucoup de réponses et d'idées pertinentes.

    Sinon, pour moi tu as deux solutions:

    1- soit définir une précision fixe (ie. valable pour tous tes nombres) et les manipuler ensuite en tant qu'entiers.

    Par exemple, si tu dois être précis au millième près et que tu veux stocker 12.345, alors tu stockes 12.345 * 1000 = 12345.

    Ainsi toutes tes opérations se feront sur des entiers, donc pas de perte de précision. A la fin, quand tu dois afficher le résultat à l'écran, tu peux toujours convertir l'entier en chaîne de caractère et la manipuler pour rajouter la virgule.

    Le +: les opérations se feront sur des entiers, donc à priori ce sera relativement rapide (plus que la solution n°2).

    Le -: attention aux limites des entiers en javascript (de -2^63 à 2^63 ?) : si (ton plus grand nombre * ( 1 / la précision)) dépasse ces limites, alors la solution n'est plus envisageable.

    Note: Cette technique est d'ailleurs utilisée dans un autre domaine: quand on travaille sur des nombres décimaux avec un hardware qui ne les supporte pas ou 'mal' (ie. qui les traite aussi vite qu'une tortue au pas de course, genre les CPU MIPS). Tu peux faire quelques recherches sur la notion de fixed-point number.


    2- soit faire des recherches sur une hypothétique librairie javascript déjà existante pour manipuler de tels nombres et pouvoir y appliquer des calculs exacts. J'imagine que le mot-clef 'big numbers' (qui à l'origine pointe plutôt pour des solutions pour stocker de très grands entiers) devrait également te permettre de dénicher des librairies supportant les nombres décimaux. Exemple.

    Le +: probablement moins de limites que la solution 1 pour les très grands / très petits nombres

    Le -: les performances seront largement revues à la baisse.
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

Discussions similaires

  1. Résultat faux d'un calcul
    Par moras13 dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 19/10/2014, 22h01
  2. [2008R2] Sum() dans un membre calculé et résultat "faux"
    Par Donpi dans le forum SSAS
    Réponses: 0
    Dernier message: 18/09/2013, 10h28
  3. [XSLT] Calcul entre deux noeuds, résultat dans un autre noeud
    Par thefutureisnow dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 06/12/2009, 15h55
  4. [BDE][PARADOX][D7]Filter et RecordCount = résultat faux
    Par N1bus dans le forum Bases de données
    Réponses: 2
    Dernier message: 15/10/2004, 21h15
  5. calcul entre 2 champs time
    Par pram dans le forum XMLRAD
    Réponses: 2
    Dernier message: 19/02/2003, 10h12

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