Как напечатать двойной с полной точностью на iOS? - PullRequest
28 голосов
/ 20 апреля 2011

Контрольный пример:

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

Результаты:

3,141593
3.141593
+3,141592653589793

Выводы:

1) Печать через NSLog () или [NSString stringWithFormat] обеспечивает очень низкую точность ...

2) Печать с помощью [NSNumber numberWithDouble] обеспечивает более высокую точность ...

Я ожидал бы получить результат намного ближе к исходному значению: 3.14159265358979323846264338327950288 (как определено в math.h)

Есть какие-нибудь подсказки?

Ответы [ 5 ]

22 голосов
/ 20 апреля 2011

Первые две строки округляются до 6 десятичных знаков, поскольку это длина округления по умолчанию для printf, унаследованная от C.

В третьей строке отображаются данные с максимальной полезной точностью - 64-битная IEEE 754 с плавающей точкойТочность числа немного меньше 16 десятичных цифр, поэтому все эти цифры литерала в math.h не имеют смысла (возможно, их можно рассматривать как защиту от возможных будущих переопределений в формате с большей точностью).

11 голосов
/ 27 мая 2012

Возможно, с ответом немного поздно, но кто-то может наткнуться на эти проблемы:

Вы должны использовать long double с максимальным форматированием 20 цифр @. 20Lg . Длинные двойные числа - это 80-битные числа с плавающей запятой, поэтому вы не получите большей точности, чем эта. Также имейте в виду, что начиная с XCode 4.3.2 константы не имеют длинных двойных обозначений, даже если многие цифры указывают на сверхдлинный двойной; -)

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

результаты:

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)
10 голосов
/ 20 апреля 2011

Попробуйте это:

NSLog(@"%.20f", M_PI);
0 голосов
/ 01 октября 2018

Попробуйте, эта работа для меня

NSLog (@ "% @", [NSString stringWithFormat: @ "% f", расстояние]);

0 голосов
/ 20 апреля 2011
NSLog(@"%@", [NSDecimalNumber numberWithDouble:M_PI]); 

немного больше точности

...