テストケース:
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で定義)
手がかりはありますか?
最初の2行は小数点以下6桁に丸めます。これは、Cから継承されたprintf
のデフォルトの丸めの長さだからです。
3行目は、有効な最大精度でデータを表示します-IEEE 754 64ビット浮動小数点数の精度は10桁の16桁よりわずかに少ないため、math.h
のリテラルの桁はすべて無意味です(おそらく、より正確な形式での将来の再定義の可能性に対する将来の保証と見なされます)。
おそらく回答としては少し遅れますが、誰かがこれらの問題に遭遇するかもしれません:
最大フォーマットが20桁のlong doubleを使用する必要があります@。20Lg。 long doubleは80ビットの浮動小数点であるため、それ以上の精度は得られません。 XCode 4.3.2以降では、多くの桁がuberlong doubleを示唆している場合でも、定数はlong 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)
これを試して:
NSLog(@"%.20f", M_PI);
これを試してください、この作品は私のために
NSLog(@ "%@"、[NSString stringWithFormat:@ "%f"、distance]);