计算莱布尼茨求和的迭代次数,用于π C++
Counting iterations of the Leibniz summation for π in C++
我的任务是询问用户,与 pi 的实际值相比,他们希望总和迭代多少位小数位精度。因此,当循环达到 3.14 时,小数点后 2 位将停止。我有一个完整的程序,但我不确定它是否真的按预期工作。我已经用计算器检查了 0 和 1 小数位,它们似乎有效,但我不想假设它适用于所有人。此外,我的代码可能有点笨拙,因为仍在学习基础知识。我们刚刚学习了循环和嵌套循环。如果有任何明显的错误或可以清理的部分,我将不胜感激任何意见。编辑:我只需要让这项工作最多小数点后五位。这就是为什么我的圆周率值不精确。很抱歉误会。
#include <iostream>
#include <cmath>
using namespace std;
int main() {
const double PI = 3.141592;
int n, sign = 1;
double sum = 0,test,m;
cout << "This program determines how many iterations of the infinite series forn"
"pi is needed to get with 'n' decimal places of the true value of pi.n"
"How many decimal places of accuracy should there be?" << endl;
cin >> n;
double p = PI * pow(10.0, n);
p = static_cast<double>(static_cast<int>(p) / pow(10, n));
int counter = 0;
bool stop = false;
for (double i = 1;!stop;i = i+2) {
sum = sum + (1.0/ i) * sign;
sign = -sign;
counter++;
test = (4 * sum) * pow(10.0,n);
test = static_cast<double>(static_cast<int>(test) / pow(10, n));
if (test == p)
stop = true;
}
cout << "The series was iterated " << counter<< " times and reached the value of pinwithin "<< n << " decimal places." << endl;
return 0;
}
莱布尼茨求和的问题之一是它具有极低的收敛率,因为它表现出亚线性收敛。在您的程序中,您还可以将计算出的π消光与给定值(6 位近似值)进行比较,而求和的重点应该是找出正确的数字。
如果所需的数字在迭代之间没有变化,您可以稍微修改代码以使其终止计算(我还添加了最大迭代次数检查)。请记住,您使用的是double
不是无限的精度数字,舍入误差迟早会影响计算。事实上,此代码的真正限制是它所需的迭代次数(获得3.141592653
的迭代次数为 2,428,700,925)。
#include <iostream>
#include <cmath>
#include <iomanip>
using std::cout;
// this will take a long long time...
const unsigned long long int MAX_ITER = 100000000000;
int main() {
int n;
cout << "This program determines how many iterations of the infinite series forn"
"pi is needed to get with 'n' decimal places of the true value of pi.n"
"How many decimal places of accuracy should there be?n";
std::cin >> n;
// precalculate some values
double factor = pow(10.0,n);
double inv_factor = 1.0 / factor;
double quad_factor = 4.0 * factor;
long long int test = 0, old_test = 0, sign = 1;
unsigned long long int count = 0;
double sum = 0;
for ( long long int i = 1; count < MAX_ITER; i += 2 ) {
sum += 1.0 / (i * sign);
sign = -sign;
old_test = test;
test = static_cast<long long int>(sum * quad_factor);
++count;
// perform the test on integer values
if ( test == old_test ) {
cout << "Reached the value of Pi within "<< n << " decimal places.n";
break;
}
}
double pi_leibniz = static_cast<double>(inv_factor * test);
cout << "Pi = " << std::setprecision(n+1) << pi_leibniz << 'n';
cout << "The series was iterated " << count << " timesn";
return 0;
}
我在此表中总结了几次运行的结果:
digits Pi iterations
---------------------------------------
0 3 8
1 3.1 26
2 3.14 628
3 3.141 2,455
4 3.1415 136,121
5 3.14159 376,848
6 3.141592 2,886,751
7 3.1415926 21,547,007
8 3.14159265 278,609,764
9 3.141592653 2,428,700,925
10 3.1415926535 87,312,058,383
你的程序永远不会终止,因为test==p
永远不会是真的。这是计算方式不同的两个双精度数字之间的比较。由于舍入误差,即使您运行无限次迭代,它们也不会相同,并且您的数学是正确的(现在不是,因为程序中PI
的值不准确)。
为了帮助您弄清楚发生了什么,请在每次迭代中打印 test
的值,以及 test
和 pi
之间的距离,如下所示:
#include<iostream>
using namespace std;
void main() {
double pi = atan(1.0) * 4; // Make sure you have a precise value of PI
double sign = 1.0, sum = 0.0;
for (int i = 1; i < 1000; i += 2) {
sum = sum + (1.0 / i) * sign;
sign = -sign;
double test = 4 * sum;
cout << test << " " << fabs(test - pi) << "n";
}
}
确保程序运行良好后,最终将停止条件更改为基于 test
和 pi
之间的距离。
for (int i=1; fabs(test-pi)>epsilon; i+=2)
- 1d 智能指针不适用于语法 (*)++
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 用于访问容器<T>数据成员的正确 API
- 重载操作程序时出错>>用于类中的字符串 memebr
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- C++中的cin.ignore()函数不适用于整个流
- 没有用于初始化C++中的变量模板的匹配构造函数
- 用于C++中带有数组和指针的循环
- 为什么它不适用于Visual 2019的原因
- 使用在用于SFINAE的void_t中具有参数的方法
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 重载==不适用于二进制树
- Insert函数不适用于2 if语句C++
- 用于矢量处理的多个线程
- 使外部项目可用于find_package CMake
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- 为什么模数运算符不适用于该代码
- 并行用于C++17中数组索引范围内的循环
- 将fold表达式与std::一起用于两个元组
- 在用于格式4的arm模拟器中实现功能时的一个问题