2009-11-04 9 views
2

Doublons possibles:
Strange problem comparing floats in objective-C
Is JavaScript’s math broken?
1.265 * 10000 = 126499.99999999999 ?????Comment faire pour contourner le problème décimal en JavaScript?

Après avoir vu this j'ai découvert que JavaScript:

0.1 + 0.2 === 0.3 

devient fausse.

Existe-t-il un moyen de contourner ce problème?

+3

http://docs.sun.com/source/806-3568/ncg_goldberg.html – nlucaroni

+1

Cela a été demandé à plusieurs reprises: http://stackoverflow.com/search?q=javascript+floating+point –

+0

Désolé pour la répétition. – camomileCase

Répondre

2

Que diriez-vous

function isEqual(a, b) 
{ 
    var epsilon = 0.01; // tunable 
    return Math.abs(a - b) < epsilon; 
} 
+0

@alex: Je ne comprends pas pourquoi vous avez changé la valeur de "0.01" à "0.0". Cette fonction retournera toujours 'false', même si les deux valeurs sont complètement identiques. Non? – ruakh

+0

@ruakh Moi non plus, il peut avoir été dans une erreur. Je vais le réparer :) – alex

1

Vous devez toujours comparer les nombres à virgule flottante en utilisant une constante (normalement appelée epsilon) pour déterminer combien deux nombres peuvent différer pour être considérés comme «égaux».

1

Utiliser les mathématiques à virgule fixe (lire: entiers) pour faire des mathématiques où vous vous souciez de ce genre de précision. Sinon, écrivez une fonction qui compare vos nombres dans une plage que vous pouvez accepter comme étant «assez proche» pour égaler.

2

Ceci est un problème inhérent aux nombres binaires qui atteint tous les principaux langages de programmation.

Convertir décimal .1 (1/10) en binaire à la main - vous trouverez qu'il a une mantisse répétée et ne peut pas être représenté exactement. Comme essayer de représenter 1/3 comme une décimale.

+0

Le problème est avec le point flottant binaire, pas les nombres binaires en général. Il existe des bibliothèques décimales à virgule flottante (mais pas sûr dans JS) qui évitent ce problème. – ScottJ

+1

Non, c'est un problème avec les nombres binaires. Vous ne pouvez pas représenter .1 comme un nombre binaire naturel.Les bibliothèques "décimales" le contournent en représentant des chiffres décimaux ou en utilisant des nombres décimaux à virgule fixe. –

+0

OK, c'est vrai. Ce que j'aurais dû dire, c'est que ce problème n'affecte pas les entiers binaires. – ScottJ

1

Juste une idée. Multipliez 10000 (ou un nombre similaire gros tant que c'est plus que votre nombre maximal de décimales) à toutes vos valeurs avant de les comparer, c'est pourquoi ils seront des entiers.

function padFloat(val) { 
    return val * 10000; 
} 

padFloat(0.1) + padFloat(0.2) === padFloat(0.3); 
1

Vous pouvez bien sûr multiplier chaque numéro comme

10 * 0.1 + 10 * 0.2 === 10 * 0.3 

qui évalue à true.

5

La meilleure et la seule réponse que j'ai trouvée qui fournit des résultats précis est d'utiliser une bibliothèque Decimal. La classe Java BigDecimal a été portée en javascript, voir ma réponse au this SO post.

Remarque: Les valeurs de mise à l'échelle "traiteront" le problème mais ne le "guériront" pas.