C++移植JS版PI近似计算代码结果错误 疑double使用不当
问题诊断
你的计算结果错误和double类型使用无关,核心问题是把莱布尼茨圆周率级数的运算逻辑写反了。
莱布尼茨求π的公式为:
π = 4 * (1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + ...)
你的初始值设置pi = 4是对的,但后续迭代的运算顺序、符号规则完全错了:
- 初始
lever = false,第一次进入循环时num自增为3,会走else分支执行pi = 4/3 + pi,也就是算成了4 + 4/3,和公式要求的「4 - 4/3」完全相反 - 运算式写反了主次:你写的是
(4/num) ± pi,正确逻辑应该是在现有pi值的基础上,交替减去、加上4/num - 函数声明为返回int但全程没有return值,属于未定义行为,虽然不一定直接导致计算错误,但属于规范问题
- 没有设置循环终止条件,程序会无限死循环占满CPU资源
修正后代码
#include <iostream> using namespace std; void calcpi() { double pi = 4.0; long long num = 3; bool is_subtract = true; // 按需调整迭代次数,莱布尼茨级数收敛极慢,100万次仅能精确到小数点后约6位 const int max_iter = 1000000; for (int i = 0; i < max_iter; i++) { if (is_subtract) { pi -= 4.0 / num; is_subtract = false; } else { pi += 4.0 / num; is_subtract = true; } num += 2; cout << pi << "\n"; } } int main() { calcpi(); return 0; }
补充说明
- 你之前猜测的double类型误用问题不存在:原代码中
four是double类型,做除法时整型的num会自动提升为double,不会出现整数除法截断结果的问题 - 不建议把计算用的变量全部声明为全局变量,把变量收敛到函数内部更易维护,也能避免全局命名空间污染
- 如果需要更高精度的π值,不建议用莱布尼茨级数,收敛速度太慢,可以换用马青公式或者Chudnovsky算法
内容的提问来源于stack exchange,提问作者Yeet
相关产品推荐
相关产品推荐

