2012-12-19 3 views
1

Possible en double:
Trouble with floats in Objective-Coutre Objective-C virgule flottante erreur

J'ai cassé ce problème à peu près aussi simple que je peux l'obtenir. N'hésitez pas à essayer la même chose et dites-moi si vous obtenez la même erreur et quelle solution vous pourriez avoir. Je l'ai déjà essayé sur plusieurs ordinateurs.

float total = 200000.0f + 154196.8f; 
NSLog(@"total: %f", total); 

La sortie est:

total: 354196.812500 

Si quelqu'un a une sorte d'explication logique, ne hésitez pas à partager.

+3

Pourquoi tag avec 'xcode' qui n'est pas lié à Xcode? –

+0

Xcode est l'environnement que j'utilise lorsque cela se produit. Essayez de ne pas changer les messages des gens la prochaine fois. –

+3

no. La mise en œuvre, au mieux, est OS X et GCC/clang (quel que soit). Le problème serait le même que si vous utilisiez un autre IDE. –

Répondre

3

Conseil:

long double total = 200000.0 + 154196.8; 
NSLog(@"total: %Lf", total); 

Sur mes impressions de la machine la valeur correcte.
Un point flottant de 32 bits a une mantisse de 23 bits, la valeur la plus proche est 0,5 + 0,25 + 0,125.
Vous devez utiliser plus de bits pour obtenir la représentation correcte.

+0

Plus de bits obtiendront * plus proche *, mais même un nombre à virgule flottante binaire 10 000 ne peut pas représenter .8. C'est le noeud du problème. Vous ne pouvez pas représenter 4/5 en virgule flottante binaire car le dénominateur est nécessairement une puissance de deux. C'est comme si l'on essayait de représenter 1/3 exactement comme une base décimale. 0.3333 converge, mais n'arrive jamais. –

7

Voir What Every Programmer Should Know About Floating-Point Arithmetic pour toute la compréhension profonde. La réponse courte est que toutes les représentations en virgule flottante ont des limites sur leur précision, et que les choses qui peuvent être exprimées en un petit nombre de chiffres en décimal peuvent ne pas être exprimables dans un petit nombre de chiffres binaires (et spécifiquement pas en virgule flottante).). Notez que si double peut améliorer les choses, ce n'est pas une panacée. Il est assez courant d'avoir de petites erreurs d'arrondi, même avec double. Vous pouvez facilement obtenir 1.99999999 quand vous attendez 2.