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 :

Précision des calculs : Erreur de (simple) multiplication, il est débile, javascript ?


Sujet :

JavaScript

  1. #1
    Membre régulier Avatar de Couin
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2014
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2014
    Messages : 137
    Points : 70
    Points
    70
    Par défaut Précision des calculs : Erreur de (simple) multiplication, il est débile, javascript ?
    Bonjour à tous ,

    Un petit utilitaire web que j'ai dev au boulot, pour préparer des paniers de matos à commander chez nos fournisseurs (chacun met dans le panier ce dont il a besoin, afin de faire commande groupée).

    J'ai un truc qui calcule le total HT par article lors de la saisie du prix unitaire et de la quantité.

    Et bien quand je mets quantité 10 pièces, prix unitaire 1.642 , le total est 16.41999999 etc etc . Si je mets 1.643 en PU, j'ai bien total 16.43 .
    Le problème est le même sur Firefox et sur Chrome, et sur 2 autres postes.

    10 * 1.06 par exemple pose aussi problème...

    Je cherchait ce qui n'était pas bon dans mon script, mais en faisant la multiplication directement dans la console, j'ai la même chose...

    L'un de nous deux (javascript ou moi) semble devoir retourner à l'école, mais moi je n'ai pas envie et j'ai passé l'age...

    Problème connu ? Y a-t-il une solution (plus propre que d'arrondir) ?

    Merkouin

  2. #2
    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 640
    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 640
    Points : 66 665
    Points
    66 665
    Billets dans le blog
    1
    Par défaut
    Une petite recherche sur ce forum avec "virgule flottante" te donnera la réponse

  3. #3
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 098
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 098
    Points : 44 675
    Points
    44 675
    Par défaut
    Bonjour,
    Citation Envoyé par Couin
    Problème connu ?
    et pas que pour JavaScript !



    Y a-t-il une solution (plus propre que d'arrondir) ?
    en quoi l'arrondi ne serait pas propre ?

    Une solution consiste à traiter des entiers, exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    MULTI = 1000;
    nbr = 10;
    pu = 1.642;
    pu_MULTI = pu * MULTI;
    console.log("Nok :", nbr * pu);
    console.log("Ok :", nbr * (pu * MULTI) / MULTI);
    console.log("Ok :", nbr * pu_MULTI / MULTI);
    donnera :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    > "Nok :" 16.419999999999998
    > "Ok :" 16.42
    > "Ok :" 16.42

  4. #4
    Membre régulier Avatar de Couin
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2014
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2014
    Messages : 137
    Points : 70
    Points
    70
    Par défaut
    hello !

    Merci pour vos réponses

    Bon les pavés de texte des virgules qui flottent, m'ont plus embrouillé qu'autre chose, j'ai arrêté de lire avant de balourder l'ordi, trop abstrait, encore pour une division qui peut pas faire un nombre précis (du genre 10 / 3, avec le 3.333333 etc etc) je veux bien comprendre, mais une bête multiplication par 10, niveau CE1, non, là je vois pas du tout.

    Pourquoi l'arrondi pas propre ? bah pareil, on m'aurait posé la question "combien font 10 x 1.642 ?" à l'école, je me serais jamais vu dire "ca fait 16.41999999 mais on va arrondir à 16.42" ... Ça me dépasse complètent, un truc comme ça

    Le MULTI pour contourner, ok mais si le PU est 1.64296 (c'est un exemple, ça peut être un prix unitaire comme autre chose) on se retrouve dans le même genre de situation.

    Ca me dépasse totalement... On envoie des fusées dans l'espace, on arrive à travailler sur de l'atome, façon de parler, mais une bête multiplication niveau 6 ans, on ne sait pas corriger sans bricolage

  5. #5
    Expert confirmé
    Avatar de Doksuri
    Profil pro
    Développeur Web
    Inscrit en
    Juin 2006
    Messages
    2 476
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 476
    Points : 4 687
    Points
    4 687
    Par défaut
    hello, le probleme de virgule flottante n'a rien a voir avec l'age mental...
    un ordinateur n'utilise pas de neurones pour fonctionner mes de vulgaires 1 & 0
    tu peux pas juste dire a l'ordi "deplace la virgule pour multiplier par 10", vu qu'il ne sait meme pas ce qu'est une virgule.

    tu ne peux pas comparer des choux & des carrotes.

    j'ai arrêté de lire avant de balourder l'ordi
    partant de la. ca ne sert plus a rien de te fournir des explications.
    si de toute facon, tu reste bute a ton "6ans d'age mental"

  6. #6
    Membre régulier Avatar de Couin
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2014
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2014
    Messages : 137
    Points : 70
    Points
    70
    Par défaut
    Trop abstrait pour moi
    ok sujet à supprimer
    bonne journée

  7. #7
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 098
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 098
    Points : 44 675
    Points
    44 675
    Par défaut
    Citation Envoyé par Couin
    Bon les pavés de texte des virgules qui flottent, m'ont plus embrouillé qu'autre chose, j'ai arrêté de lire avant de balourder l'ordi, trop abstrait,
    si tu ne veux pas te compliquer la vie et ne pas chercher à comprendre le pourquoi il te reste une solution le papier et le crayon, pas la calculette elle suit le même schéma.


    Citation Envoyé par Couin
    Le MULTI pour contourner, ok mais si le PU est 1.64296
    rien ne t'empêches d'augmenter la valeur pour coller à la réalité de tes valeurs, entre parenthèse dans ce cas précis il n'y a pas d'erreur si tu ajustes MULTI au nombre de décimal à traiter soit MULTI = 1e5.


    Citation Envoyé par Couin
    On envoie des fusées dans l'espace, ..., on ne sait pas corriger sans bricolage
    et pourtant il utilise ce bricolage !


    Citation Envoyé par Couin
    ok sujet à supprimer
    ce n'est pas parce que tu refuses, ou que tu as la flemme, de comprendre que les autres feront pareil.

  8. #8
    Membre régulier Avatar de Couin
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2014
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2014
    Messages : 137
    Points : 70
    Points
    70
    Par défaut
    Re,

    Non, pas du refus ni de la flemme, mais je n'arrive pas du tout à imager le truc
    Nous n'avons pas forcément tous les mêmes capacités, ce qui est évident pour certains ne l'est pas forcément pour d'autres (c’est ce que l'on me répond quand la situation est dans l'autre sens, à savoir quand j'explique un truc qui me parait simple à quelqu'un pour qui ce n'est pas compréhensible).
    Je pige pas du tout pourquoi ca poste problème avec 1.642 et pas 1.641 ni 1.643
    Avec un exemple concret par exemple basé sur ces 2 valeurs, je comprendrait peut être mieux, mais là euh

    Pour le papier, pas pratique de le changer à chaque fois aussi Pour la calculette, je viens de tester, elle me donne le bon résultat.
    Pour la suppression, c'était pour ne pas avoir un sujet de plus parmi les 80 pages de résultats de la recherche par "virgule flottante".

  9. #9
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 395
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 395
    Points : 15 756
    Points
    15 756
    Par défaut
    tu as surement affiché le contenu brut de la variable.
    en utilisant les méthode de formatage des nombres, le code suivant affiche le résultat attendu :
    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
    let prix_unitaire = 1.642;
    let quantite = 10;
     
    const calcul = prix_unitaire * quantite;
     
    console.log(calcul); // affiche 16.419999...
     
     
    const formatage_3_chiffres = new Intl.NumberFormat("fr-FR", {
    	"style" : "decimal",
    	"minimumFractionDigits" : 3,
    	"maximumFractionDigits" : 3,
    });
     
    console.log(formatage_3_chiffres.format(calcul)); // affiche 16,420

  10. #10
    Membre régulier Avatar de Couin
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2014
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2014
    Messages : 137
    Points : 70
    Points
    70
    Par défaut
    Hello,

    En effet, dans la fonction de calcul, je récupère les valeurs des deux champs et je fais la multiplication, le résultat est envoyé dans un troisième champs (en lecture seule).

    Par simplicité je me suis rabattu sur la méthode "MULTI" de NoSmoking (merki).

    Le code fourni dans ta réponse fonctionne également

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

Discussions similaires

  1. [XL-2007] Précision des calculs très aléatoires
    Par deck06 dans le forum Excel
    Réponses: 0
    Dernier message: 15/02/2021, 19h54
  2. [Toutes versions] Précision des calculs dans les feuilles Excel
    Par PPz78 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 13/12/2015, 00h05
  3. Précision des calculs
    Par guitalex dans le forum C++
    Réponses: 10
    Dernier message: 29/09/2014, 01h07
  4. Simple précision sur l'erreur #1009
    Par NoArgl dans le forum ActionScript 3
    Réponses: 0
    Dernier message: 19/11/2009, 20h15
  5. Erreur dans des calculs avec des dates
    Par Oliv'83 dans le forum Requêtes et SQL.
    Réponses: 5
    Dernier message: 31/07/2008, 11h23

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