使用Viete嵌套平方根公式计算PI时结果异常的问题排查
问题:用Viete嵌套平方根公式近似π的C++代码错误排查
我尝试用Viete的2的嵌套平方根公式近似计算圆周率π,编写了如下C++代码:
#include <iostream> #include <iomanip> #include <cmath> using namespace std; int main() { int k; //variable for user input int n = 1; //built integer that causes the program to loop double result; //greeting message, start of program cout << "Welcome to the Approx PI program.\n"; cout << "Please enter in a value for k...\n"; cin >> k; //if user inputs a number outside the interval while (k < 1 || k > 30) { cout << "Invalid ---k must be >=1 and <=30\n"; cout << "Please enter in a value for k...\n"; cin >> k; } //calculating PI with the nested square root formula while (n <= k - 1) { result = sqrt(2 + result); n++; } result = pow(2, k) * sqrt(2 - result); //outputs the result, end of program cout << "Approx PI = " <<setprecision(20)<<fixed<<result<<endl; return 0; }
但输入k=28时,程序输出结果为4;输入k=29或30时,结果为0。我预期k=30时应得到结果:3.14245127249413367895,请问我的代码哪里出错了?
解答
你的代码存在两个关键问题,其中未初始化变量是导致异常输出的核心原因:
result变量未初始化
你声明了double result;但没有赋初始值,这会导致它的初始值是内存中的随机垃圾值。Viete公式的迭代起点必须是0.0,因为第一层嵌套根号的计算是sqrt(2 + 0),后续迭代需要基于这个正确起点展开。
未初始化的垃圾值会让迭代过程完全偏离正确路径,当k增大时,迭代结果会逐渐收敛到2(因为sqrt(2+2)=2,进入不动点循环),此时sqrt(2 - result)会趋近于0,最终导致pow(2,k)*0输出0;k=28时的异常输出4,是垃圾值迭代过程中偶然出现的中间错误结果。可选优化:
pow(2,k)的精度问题
虽然不是当前错误的直接原因,但用pow计算2的整数次幂会引入微小精度误差。对于k<=30的场景,用static_cast<double>(1LL << k)代替pow(2,k)精度更高——因为2^30在double的精确表示范围内,移位运算的结果完全准确。
修正后的代码
#include <iostream> #include <iomanip> #include <cmath> using namespace std; int main() { int k; int n = 1; double result = 0.0; // 初始化迭代起点为0.0 cout << "Welcome to the Approx PI program.\n"; cout << "Please enter in a value for k...\n"; cin >> k; while (k < 1 || k > 30) { cout << "Invalid ---k must be >=1 and <=30\n"; cout << "Please enter in a value for k...\n"; cin >> k; } while (n <= k - 1) { result = sqrt(2 + result); n++; } // 用移位运算替代pow,提升精度 result = static_cast<double>(1LL << k) * sqrt(2 - result); cout << "Approx PI = " << setprecision(20) << fixed << result << endl; return 0; }
修正后输入k=30,会得到你预期的近似值:3.14245127249413367895。
内容的提问来源于stack exchange,提问作者Aacro
相关产品推荐
相关产品推荐

