我一直在开发一个简单的 C++ 程序,用 Bellard 公式来近似 pi。无论它尝试计算多少位数,结果都是数字 3.145063。
我尝试将其从存储为浮点型更改为双精度型,因为我认为它可能只是四舍五入以适应较小的数据类型,但它仍然不起作用。
这是我的代码:
#include <iostream>
#include <cmath>
double approximate(int digits) {
double summed = 0;
for (int n = 0; n < digits; n++) {
summed += (pow(-1, n) / pow(2, n * 10)) * ((-(pow(2, 5)) / (4 * n + 1)) - (1 / (4 * n + 3)) + (pow(2, 8) / (10 * n + 1)) - (pow(2, 6) / (10 * n + 3)) - (pow(2, 2) / (10 * n + 5)) - (pow(2, 2) / (10 * n + 7)) + (1 / (10 * n + 9)));
}
return (1 / pow(2, 6)) * summed;
}
int main() {
std::cout << "How many digits?: ";
std::string its;
std::getline(std::cin, its);
std::string approx = std::to_string(approximate(std::stoi(its)));
std::cout << approx << std::endl;
}
如前所述,如果您将该行分成多个语句,您会发现您正在执行整数除法而不是浮点除法。
(1 / (4 * n + 3))
和
(1 / (10 * n + 9))
不正确。简单的修正是使用 1.0 强制进行浮点除法:
#include <iostream>
#include <cmath>
double approximate(int digits) {
double summed = 0;
for (int n = 0; n < digits; n++) {
summed += (pow(-1, n) / pow(2, n * 10)) *
((-(pow(2, 5)) / (4 * n + 1)) - (1.0 / (4 * n + 3)) + // <-- 1.0
(pow(2, 8) / (10 * n + 1)) -
(pow(2, 6) / (10 * n + 3)) -
(pow(2, 2) / (10 * n + 5)) -
(pow(2, 2) / (10 * n + 7)) + (1.0 / (10 * n + 9))); // <-- 1.0
}
return (1 / pow(2, 6)) * summed;
}
int main() {
std::string approx = std::to_string(approximate(10));
std::cout << approx << std::endl;
}
输出:
3.141593
代码中的其他内容也可以改进,更具体地说是对
pow
的调用。你知道 pow(2,2)
、pow(2,5)
、pow(2,8)
等都是常数。不需要每次 for
循环迭代时都计算它们。只需创建这些常量并使用它们即可。