【问题标题】:How to printf long long如何打印f long long
【发布时间】:2011-06-19 02:36:32
【问题描述】:

我正在做一个近似 PI 的程序,我正在尝试使用 long long,但它不起作用。 这是代码

#include<stdio.h>
#include<math.h>
typedef long long num;
main(){
    num pi;
    pi=0;
    num e, n;
    scanf("%d", &n);
    for(e=0; 1;e++){
      pi += ((pow((-1.0),e))/(2.0*e+1.0));
      if(e%n==0)
        printf("%15lld -> %1.16lld\n",e, 4*pi);
      //printf("%lld\n",4*pi);
    }
}

【问题讨论】:

  • 我猜你的问题更多的是scanf而不是printf
  • pow((-1.0),e) 会更好地表达为e % 2 ? 1 : -1

标签: c long-integer pi


【解决方案1】:

%lld 是标准的 C99 方式,但这不适用于我正在使用的编译器(mingw32-gcc v4.6.0)。在此编译器上执行此操作的方法是:%I64d

所以试试这个:

if(e%n==0)printf("%15I64d -> %1.16I64d\n",e, 4*pi);

scanf("%I64d", &n);

我知道以完全可移植的方式执行此操作的唯一方法是使用 &lt;inttypes.h&gt; 中的定义。

在你的情况下,它看起来像这样:

scanf("%"SCNd64"", &n);
//...    
if(e%n==0)printf("%15"PRId64" -> %1.16"PRId64"\n",e, 4*pi);

确实很丑……但至少它是便携的。

【讨论】:

  • 这里负责的不是你的编译器,而是你的 C 库。您正在使用 Microsoft C 库,它不支持 %lld,这是 C99 功能(尽管 inttypes.h 也是如此)。
  • 更具体地说,它是 msvcrt.dll,它是 C 标准库的古老(大约 1998 年)版本,最初是为 VC++ 6.0 编写的,为了向后兼容而随 Windows 一起提供。 MinGW 使用那个古老的版本,因为这是唯一一个随 Windows 开箱即用的版本。但现代 VC++ 运行时处理 %lld 正确。
  • Visual C++ 2013 似乎支持 %lld 格式元素
  • @PavelMinaev msvcrt.dll Windows 自带的并不古老。
  • 它已经打补丁了,当然,但我没有听说自 VC++ 6.0 天以来它的实际功能有任何更新。
【解决方案2】:
  • 您的scanf() 语句也需要使用%lld
  • 您的循环没有终止条件。
  • 表达式中的括号太多而空格太少

    pi += pow(-1.0, e) / (2.0*e + 1.0);
    
  • 您在循环的第一次迭代中添加一个,然后在“pi”的值上添加一个零;这不会改变太多的值。
  • 您应该为main() 使用显式返回类型int
  • 总的来说,当它忽略其参数时,最好指定 int main(void),尽管与其他语句相比,这不是一个明确的陈述。
  • 我不喜欢 C99 中授予的明确许可,以省略 main() 末尾的返回,并且不要自己使用它;我写return 0; 是明确的。

我认为使用long long 编写的整个算法是可疑的;数据类型可能应该更像long double%Lf 用于scanf() 格式,%19.16Lf 用于printf() 格式。

【讨论】:

    【解决方案3】:

    首先,%d 代表int

    所以%1.16lld 没有意义,因为 %d 是一个整数

    你做的那个 typedef 也是不必要的,直接使用 type ,使代码更具可读性。

    你要使用的类型是double,用于计算圆周率 然后使用%f%1.16f

    【讨论】:

    • 这并不是真正的“非法”......我认为它是特定于 MSVC 的。
    • 不正确。阅读spec for printf%lld 正是您打印long long 的方式。 (当然,1.16 可能不会做你想做的事......但它完全有效。这意味着使用最小字段宽度为 1 并打印 16 位数字。)
    • @Mehrdad 你的意思是%lld?它在 C99 7.19.6.1 中指定。
    • @Pascal:哦,我不知道,甚至更好。 @hexa:对不起,我指的是lld,而不是小数点……我以为这就是你的意思,我的错。
    • MSVC 对 64 位 long long 格式使用 %I64d%lld 等格式。
    【解决方案4】:
        // acos(0.0) will return value of pi/2, inverse of cos(0) is pi/2 
        double pi = 2 * acos(0.0);
        int n; // upto 6 digit
        scanf("%d",&n); //precision with which you want the value of pi
        printf("%.*lf\n",n,pi); // * will get replaced by n which is the required precision
    

    【讨论】:

    • 虽然此代码 sn-p 可能是解决方案,但包含解释确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因
    • 虽然此代码可能会解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提出问题的人。请edit您的答案添加解释并说明适用的限制和假设。
    • 当然,我会添加更多细节@double-beep
    猜你喜欢
    • 2023-03-13
    • 2012-09-11
    • 2011-03-13
    • 1970-01-01
    • 1970-01-01
    • 2015-08-10
    • 2020-05-14
    • 1970-01-01
    相关资源
    最近更新 更多