2010-11-17 7 views
1

Nous remarquons que cela se produit à la fois en javascript et en VB.net 2.0. Donc, fondamentalement, à la fois dans le côté serveur et le code côté client.javascript et VB.net retournant des résultats incorrects

Fondamentalement, si vous exécutez cette équation 975328 - 153279.43 vous obtenez la réponse suivante 822048.57000000007.

Toutefois, si vous exécutez 975328 - 153279.4, 975328 - 153279.433 ou 975328 - 153279.5, tout est renvoyé correctement.

Toutes les idées doivent POURQUOI le système calcule le 975328 - 153279.43 avec une réponse avec 11 décimales? Sans parler de l'ajout du 7 à la 11e décimale, rendant ainsi la réponse à l'équation incorrecte.

Bien sûr, je sais que je peux couper, définir la réponse à des décimales appropriées, etc., etc., mais nous sommes plus intéressés à savoir POURQUOI il renvoie une telle réponse.

nu à l'esprit, ce qui précède est prouvé en entrant simplement l'équation dans la fenêtre immidiate, ellimnating ainsi varibables tels que les types d'objets, etc., etc.

Merci pour l'aide, Ken

+2

Quel type de données avez-vous utilisé dans VB?Cela peut faire une grande différence – Pondidum

+4

[Ce que tout scientifique informatique devrait savoir sur l'arithmétique en virgule flottante] (http://docs.sun.com/source/806-3568/ncg_goldberg.html) –

+1

+1 Parce qu'il n'est pas juste de downvote sans commentaire. Je suppose que downvote peut être parce que c'est une question de débutant - ce serait injuste si c'était le cas. – MarkJ

Répondre

5

Pour la même raison, vous ne pouvez pas exprimer exactement 1/3 sous forme décimale (base 10). Vous pouvez entrer vos numéros dans la base 10, mais tout l'arithmétique se passe dans la base 2 (binaire). Donc, cette valeur de base 10 doit d'abord être convertie en base 2, et vous aurez probablement besoin de plus de bits pour la représenter que pour le type double standard, s'il est même possible de représenter exactement le nombre en binaire.

Un autre nombre commun à rechercher pour cette erreur est .1. Lorsqu'il est converti en binaire, tout nombre décimal avec .1 se répète à l'infini après le point décimal. Ainsi, il n'y a aucun moyen d'exprimer avec précision la valeur en binaire.

Dans VB.Net, vous avez au moins le type décimal que vous pouvez utiliser pour gérer ce genre de chose. Il est beaucoup plus lent, mais il devrait gérer avec précision ce genre de calcul. Je ne suis pas sûr que la solution javascript est.

1

Vous devez savoir que les nombres à virgule flottante n'auront qu'une précision fixe. Vous ne pouvez pas afficher correctement tous les nombres par virgule flottante, de sorte que certains calculs peuvent causer cette imprécision à « surface »

Un nombre à virgule flottante est présenté comme un « int » + un bitshift ...

Jetez un coup d'oeil ici Représentation interne Les nombres à virgule flottante sont généralement groupés dans une donnée d'ordinateur sous la forme du bit de signe, du champ d'exposant et du mantelet, de gauche à droite. Pour les formats binaires IEEE 754, ils sont répartis comme suit:

 
Type Sign Exponent Significand Total bits Exponent bias Bits precision 

Half 1 5   10   16    15   11 
(IEEE 754-2008) 

Single 1 8   23   32    127   24 

Double 1 11   52   64   1023   53 

Quad 1 15   112   128   16383   113 
1

Javascript utilise type float, pour stocker ces valeurs, et en résumé, le type de données float ne stocke pas le nombre exact en mémoire. Habituellement, son meilleur à utiliser des entiers pour effectuer des calculs et alors vous pouvez toujours diviser par 100.0 pour lancer à n'importe quel point décimal que vous souhaitez. Vous pouvez également utiliser toFixed (DECIMAL_PLACES) sur l'objet pour l'arrondir au point décimal souhaité.

+0

L'utilisation de nombres entiers est mauvaise. Ils ont la mauvaise habitude de tronquer la mantisse, ce qui peut être important. –