当前位置: 首页 > 知识库问答 >
问题:

莱布尼兹公式

潘俊
2023-03-14

这是我的密码

#include<stdio.h>
#include<math.h>
int main()
{
    int n,i;
    long double s=0;
    scanf("%d",&n);
    for(i=0;i<n;i++){
        s+=(long double)pow(-1,i)/(2*i+1);
    }
    printf("%Lf\n",s);
    return 0;
}

有人能告诉我为什么我不能精确到小数点后第15位吗?我的目的不是打印pi/4的值,我只需要打印给定n的总和

共有1个答案

麻烨
2023-03-14

问:为什么...精确到小数点后第15位?
A:要显示小数点后的15位小数点,请使用格式“%0.15f”。要计算收敛的小数点后15位,至少n需要非常大。

正如@user3386109所提到的,“结果中的错误以1/(2n+1)为界”,因此大约需要5e14次迭代。(粗略估计:在我的电脑上10天。)由于典型的double的精度约为pow(2,53)中的1部分或9E15中的1部分,因此double的计算已达到极限。下面的代码比较了计算的顺序,以减少误差,但充其量,误差仍将在9E15中至少0.5部分。

当级数项在极限附近振荡时,在n次迭代后停止时,可以添加下一次迭代的1/2的最后一次迭代。这将提高大约1位的精度。

正如其他人提到的,还有其他方法可以更快地计算?。

根据@user3386109的良好观察更新。

在对术语求和时,代码可以按照不同的顺序对它们求和。下面的两种方法说明,当先将小项求和在一起时,会较早地获得较稳定的结果。我最多只能指望一个好一点的答案。

//Leibniz formula for pi/4
typedef float fp;

fp LeibnizForward(unsigned n) {
  volatile fp sum = 0.0;
  fp sign = 1.0;
  unsigned i = 1;
  while (n-- > 0) {
    sum += sign / i;
    sign = -sign;
    i = (i + 2);
  }
  return sum;
}

fp LeibnizReverse(unsigned n) {
  volatile fp sum = 0.0;
  fp sign = 1.0;
  unsigned i = 2 * n - 1;
  if (n % 2 == 0)
    sign = -sign;
  while (n-- > 0) {
    sum += sign / i;
    sign = -sign;
    i = (i - 2);
  }
  return sum;
}

void PiTest(unsigned n) {
  printf("%u\n", n);
  static const fp pic = 3.1415926535897932384626433832795;
  const char *format = "%s %0.9f\n";
  printf(format, "pi-", nextafterf(pic,0));
  printf(format, "pi ", pic);
  printf(format, "pi+", nextafterf(pic,4));
  fp pif = LeibnizForward(n) * 4;
  printf(format, "pif", pif);
  fflush(stdout);
  fp pir = LeibnizReverse(n) * 4;
  printf(format, "pir", pir);
  fflush(stdout);
}

int main(void) {
  PiTest(0);
  PiTest(1);
  PiTest(10);
  PiTest(100);
  PiTest(1000);
  PiTest(10000);
  PiTest(100000);
  PiTest(1000000);
  PiTest(10000000);
  PiTest(100000000);

  return 0;
}

0
pi- 3.141592503
pi  3.141592741
pi+ 3.141592979
pif 0.000000000
pir 0.000000000
1
pi- 3.141592503
pi  3.141592741
pi+ 3.141592979
pif 4.000000000
pir 4.000000000
10
pi- 3.141592503
pi  3.141592741
pi+ 3.141592979
pif 3.041839600
pir 3.041839600
25
pi- 3.141592503
pi  3.141592741
pi+ 3.141592979
pif 3.181576490
pir 3.181576729
100
pi- 3.141592503
pi  3.141592741
pi+ 3.141592979
pif 3.131592512
pir 3.131592751
1000
pi- 3.14 1592503
pi  3.14 1592741
pi+ 3.14 1592979
pif 3.14 0592575
pir 3.14 0592575
10000
pi- 3.141 592503
pi  3.141 592741
pi+ 3.141 592979
pif 3.141 498566
pir 3.141 492605
100000
pi- 3.1415 92503
pi  3.1415 92741
pi+ 3.1415 92979
pif 3.1415 85827
pir 3.1415 82489
1000000
pi- 3.14159 2503
pi  3.14159 2741
pi+ 3.14159 2979
pif 3.14159 5364
pir 3.14159 1549
10000000
pi- 3.14159 2503 previous float
pi  3.14159 2741 machine float pi
pi+ 3.14159 2979 next float
pif 3.14159 6794
pir 3.14159 2503
100000000 Additional iterations do not improve the result.
pi- 3.14159 2503
pi  3.14159 2741 
pi+ 3.14159 2979
pif 3.14159 6794
pir 3.14159 2503
1000000000
pi- 3.14159 2503
pi  3.14159 2741
pi+ 3.14159 2979
pif 3.14159 6794
pir 3.14159 2503
 类似资料:
  • 我们看到的是Apache Nifi和Gobblin,它们似乎在意图上有重叠。什么样的用例最适合哪个平台?它们将如何符合上面的用例? 谢了!

  • 更新时间:2019-03-01 14:56:32 发布公告包含了每次发布的时间,版本,该版本的新功能,以及与旧版本有区别的地方。

  • 我正在使用Mochito,无法返回使用MarshallSendReceive进行的api调用的模拟响应。 以下是服务api调用(其中serviceRequest的类型为ValidateRequest,HeaderComposingCallback实现WebServiceMessageCallback) 这里是JUnit测试中的模拟,validateResponse是创建的对象,填充了值,但在运行下

  • 概述 该尼龙滑轮可用于8mm宽零件上的平滑线性运动。它具有8mm宽的槽,可以精确地配合8mm宽度的梁或杆。每个滑轮需要2个轴承。 参数 内径:14.5mm 长度:16mm 配合轴承:滚珠轴承4x8x3mm 材质:尼龙 尺寸

  • 2023.10.01国庆节上午10点 Java开发实习生,在杭州,公司是一个自研公司,看官网介绍是做云数据库解决方案的。 大概半个小时,全程拷打,感觉发挥地的不好 每次问到一个技术,先问有没有看过源码 1. 自我介绍 2. 介绍项目,项目分工,项目技术选型是怎么做的,为什么用这些技术?项目上线没有 3. 项目中做过哪些测试?怎么做的? 4. 用过PostgreSQL这个数据库吗?了解过,那Post

  • 2023.7.27 时长:30min 一面 自我介绍 校园社团经历中,如何整理前端学习路线 在前端中,比较难的部分在哪里(JS) JS 中比较难的部分是哪里 原型链是什么 异步的处理方案 闭包是什么,它的使用场景 防抖和节流 输入一个地址,浏览器做了哪些处理 Vue的生命周期函数 了解过 Vue 的源码吗,如何学习的 技术分享会是什么 反问: 贵公司的技术栈 主要开发的项目 学习源码的建议 面试中