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 :

Bizarrerie calcul Mathématique


Sujet :

JavaScript

  1. #1
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut Bizarrerie calcul Mathématique
    Bonjour,

    Je travail actuellement avec Node RED et j'écris des fonctions en JavaScript.

    Je suis tombé sur une bizarrerie ce matin.

    Je fais le calcul suivant :
    - parseInt( (1.12*100)%100 ) => retourne bien 12
    - parseInt( (1.13*100)%100 ) => retourne 12 ?!

    En décortiquant mes calculs, il s'avère que 1.13*100 = 12.9999
    Même en faisant un parseFloat sur ma variable qui contient mon 1.12/1.13 ... j'ai la même chose.

    En attendant je m'en suis sortis en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Math.round(parseFloat(msg.payload.i[n])*100)%100; // 1.13*100 = 112.9999 ??
    Quelqu'un aurait-il une explication rationnelle ou une façon de faire plus propre ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var t = parseFloat(msg.payload.i[n]) * 100;
    node.warn("index: " + msg.payload.i[n] + " t: " + t );
    "index: 1.12 t: 112.00000000000001"
    "index: 1.13 t: 112.99999999999999"

  2. #2
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 888
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 888
    Points : 6 632
    Points
    6 632
    Par défaut
    Ce n'est pas un phénomène propre à Javascript, mais propre aux flottants.

    Les nombres sont manipulés sous forme binaire, et si un nombre entier a toujours une représentation binaire finie, ce n'est pas forcément le cas d'un nombre décimal. Par exemple:
    Code txt : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
                       ___   
    1.12 =>  1.00011110101

    Autrement dit, un nombre peut avoir une notation finie en base 10 mais une notation infinie en base 2 (ou plus généralement dans une autre base)..

    Comme les nombres flottants sont stockés sur un nombre limité de bits, disons 64bits dont 1 est réservé au signe, 11 à l'exposant et 52 aux chiffres significatifs (la mantisse), tout calcul impliquant un flottant donnera lieu à plusieurs arrondis, à commencer par le nombre flottant lui même, et le résultat de l'opération. En d'autres termes, le calcul est effectué avec des valeurs approchées, et le résultat final a de grandes chances d'être aussi une valeur approchée (sauf alignement particulier des astres).

    L'exemple le plus connu est le test 0.1 + 0.2 == 0.3 qui renvoie invariablement false.




    Concernant parseInt() et parseFloat(): ces fonctions n'ont pas pour vocation de transformer des entiers en flottants ou des flottants en entiers. Elles sont faites pour chercher un flottant ou un entier dans une chaîne de caractères. Il ne faut pas leur en demander plus. Donc tu auras besoin d'utiliser parseFloat() uniquement pour msg.payload.i[n] si c'est une chaîne de caractères.

    Pour ce qui est de l'utilisation de Math.round(), ça me semble être la bonne solution. Tu peux carrément écrire Math.round(1.12*100%100).

  3. #3
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    Merci pour le retour complet.
    Je m'en suis sortis en splittant avec le "." et en ajoutant les deux entiers obtenus..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var t = msg.payload.i[n].split(".");
    var res = (t[0]*100 + t[1])%100; // ce qui revient à prendre t[1] directement :)

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

Discussions similaires

  1. calcul mathématique en C#
    Par belmansour tidjani dans le forum C#
    Réponses: 7
    Dernier message: 04/09/2007, 17h34
  2. Calcul mathématique en C
    Par _SamSoft_ dans le forum C
    Réponses: 3
    Dernier message: 26/04/2007, 18h18
  3. logiciel de calculs mathématiques avancés
    Par jlassiramzy dans le forum Autres Logiciels
    Réponses: 3
    Dernier message: 21/03/2007, 20h26
  4. [PHP-JS] calculs mathématiques avancés en php
    Par jejerome dans le forum Langage
    Réponses: 8
    Dernier message: 12/07/2006, 13h05
  5. calculs mathématiques avec des "racines)
    Par emmanuel4945 dans le forum Access
    Réponses: 1
    Dernier message: 30/01/2006, 21h40

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