【问题标题】:How to print a double with full precision on iOS?如何在 iOS 上以全精度打印双精度?
【发布时间】:2011-04-20 10:43:20
【问题描述】:

测试用例:

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 中)

有什么线索吗?

【问题讨论】:

    标签: iphone cocoa-touch double precision nslog


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      您应该使用最大格式为 20 位的 long double @.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】:

        试试这个:

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

        【讨论】:

        • 谢谢,但这无济于事。结果是3.14159265358979311600,四舍五入很差(最后5个数字好像错了)
        • @Ariel:那是因为它们是将真实值四舍五入为 52 位二进制数字,然后将结果转换回十进制的结果。
        【解决方案4】:

        试试这个,这对我有用

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

        【讨论】:

          【解决方案5】:
          NSLog(@"%@", [NSDecimalNumber numberWithDouble:M_PI]); 
          

          更精确一点

          【讨论】:

          • 谢谢,但这无济于事。结果是3.141592653589793792,四舍五入很差(最后3个数字好像错了)
          猜你喜欢
          • 2010-10-07
          • 1970-01-01
          • 1970-01-01
          • 2016-04-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多