2011-04-20 92 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)