如何在iOS上完全精确地打印双精度?

时间:2011-04-20 10:43:20

标签: iphone cocoa-touch double precision nslog

测试用例:

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 个答案:

答案 0 :(得分:22)

前两行舍入到6位小数,因为这是从C继承的printf的默认舍入长度。

第三行显示具有最大有用精度的数据 - IEEE 754 64位浮点数的精度略小于16位小数,因此math.h中文字的所有数字都是毫无意义的(也许它们可以被视为面向未来,以更精确的格式对未来可能的重新定义。)

答案 1 :(得分:10)

试试这个:

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

答案 2 :(得分:10)

作为回答可能有点迟,但有人可能偶然发现这些问题:

你应该使用long double,最大格式为20位 @。20Lg 。 长双精度是80位浮点数,因此你不会获得更好的精度。 还要注意,从XCode 4.3.2开始,常量不是长双符号,即使许多数字表示uberlong double; - )

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)

答案 3 :(得分:0)

尝试一下,这对我有用

NSLog(@“%@”,[NSString stringWithFormat:@“%f”,distance]);

答案 4 :(得分:-2)

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

更精确一点