2011-04-20 2 views
26

Cas de test:Comment imprimer un double en toute précision sur iOS?

NSLog(@"%f", M_PI); 
NSLog(@"%@", [NSString stringWithFormat:@"%f", M_PI]); 
NSLog(@"%@", [NSNumber numberWithDouble:M_PI]); 

Résultats:

3,141593
3,141593
3,141592653589793

Conclusions:

1) Impression via NSLog() ou [NSString stringWithFormat ] fournir une précision très faible ...

2) Impression via [NSNumber numberWithDouble] offre une meilleure précision ...

Je me serais attendu à obtenir un résultat beaucoup plus proche de la valeur d'origine: 3.14159265358979323846264338327950288 (tel que défini en math.h)

Des indices?

Répondre

21

Les deux premières lignes rondes à 6 décimales parce que c'est la longueur d'arrondi par défaut pour printf hérité de C.

Le la troisième ligne affiche les données avec la précision maximale utile - un nombre à virgule flottante 64 bits IEEE 754 a un peu moins de 16 chiffres décimaux de précision, donc tous ces chiffres du littéral dans math.h sont inutiles (peut-être qu'ils peuvent être considérés comme une protection contre une possible redéfinition future dans un format avec plus de précision).

+0

Brillant, merci! –

10

Essayez ceci:

NSLog(@"%.20f", M_PI); 
+1

Merci, mais ça n'aide pas. Le résultat est 3.14159265358979311600, ce qui est mal arrondi (les 5 derniers chiffres semblent faux) –

+1

@Ariel: c'est parce qu'ils sont le résultat de l'arrondi de la valeur vraie à 52 chiffres binaires, puis de la conversion du résultat en décimal. –

-1
NSLog(@"%@", [NSDecimalNumber numberWithDouble:M_PI]); 

un peu plus de précision

+0

Merci, mais ça n'aide pas. Le résultat est 3.141592653589793792, ce qui est mal arrondi (les 3 derniers chiffres semblent faux) –

10

Peut-être un peu tard d'une réponse mais quelqu'un pourrait tomber par hasard sur ces problèmes:

Vous devez utiliser long double avec un formatage maximum de 20 chiffres @ .20Lg. Les longs doubles sont des points flottants de 80 bits, vous n'obtiendrez donc pas une meilleure précision. Sachez aussi que de XCode 4.3.2 les constantes ne sont pas en long double notation, même si les chiffres suggèrent une nombreux à double uberlong ;-)

NSLog(@"%.21g", M_PI); 

// with cast because M_PI is not defined as long double 
NSLog(@"%.21Lg", (long double)M_PI); 

// with corrected long double representation (#.####L): 
//         v from here on overhead 
NSLog(@"%.21Lg", 3.14159265358979323846264338327950288L); 

// alternative for creating PI 
NSLog(@"%.21Lg", asinl(1.0)*2.0); 
// and a funny test case: 
NSLog(@"%.21Lg", asinl(1.0)*2.0 - M_PI); // on second thought, not that funny: should be 0.0 

les résultats sont les suivants:

p[5528:f803] 3.141592653589793116 (actually 16 digits standard double precision) 
p[5528:f803] 3.141592653589793116 
p[5528:f803] 3.14159265358979323851 
p[5528:f803] 3.14159265358979323851 
p[5575:f803] 1.22514845490862001043e-16 (should have been 0.0) 
Questions connexes