2011-04-20 58 views
26

测试用例:如何在iOS上以全精确度打印双精度数据?

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 ]提供了一个非常低的精度...

通过[NSNumber的numberWithDouble]提供了更好的精度...

我本来期望得到更接近原始值的结果

2)印刷:3.14159265358979323846264338327950288(定义在math.h)

任何线索?

回答

21

前两行,因为这是从C

继承为printf默认的舍入长度第三行显示具有最大有用精度的数据 - IEEE 754 64位浮点数的精度略低于16位十进制数,所以math.h中的所有这些数字都是毫无意义的(也许它们可以被看作是对未来可能的重新定义的更具精确度的未来重新定义)。

+0

辉煌,谢谢! – 2011-04-20 11:03:10

10

尝试这种情况:

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

谢谢,但它没有帮助。结果是3.14159265358979311600,这是非常凑整的(最后5个数字看起来是错误的) – 2011-04-20 10:55:13

+1

@Ariel:这是因为它们是将真实值舍入为52个二进制数字并将结果转换回十进制的结果。 – 2011-04-20 11:25:23

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

一点更精确轮6个小数

+0

谢谢,但它没有帮助。结果是3.141592653589793792,这是非常圆润的(最后3个数字似乎是错误的) – 2011-04-20 11:00:55

10

也许有点晚了作为一个答案,但有人可能会偶然发现了这些问题:

你应该使用长双用的20位@ .20Lg最大格式。 长双打是80位浮点,所以你不会得到比这更好的精度。 注意也作为的Xcode 4.3.2常数不长双符号,即使许多数字表明一个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 

结果是:

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)