已知等比数列前三项和与积,结合推导公式编写C++求解程序
C++ 实现等比数列前三项计算(已知和与乘积)
核心逻辑回顾
设等比数列前三项为a, b, c,根据推导公式:
- 中间项
b = ∛p(由等比中项性质,乘积p = b³) - 首项
a满足二次方程:a² + (b - s)a + b² = 0,解出a后,第三项c = b²/a(等比中项变形)
实现步骤
- 输入和
s与乘积p,先排除无效输入(p=0,因为等比数列项不能为0) - 计算中间项
b,使用std::cbrt(支持正负实数的立方根计算,比pow更可靠) - 计算二次方程的判别式
D = (b - s)² - 4*b²,判断是否存在实根 - 若判别式非负,解出两个可能的首项
a,并计算对应第三项c - 输出有效结果
完整代码示例
#include <iostream> #include <cmath> #include <iomanip> int main() { double s, p; std::cout << "输入等比数列前三项的和s与乘积p: "; std::cin >> s >> p; // 等比数列不能有0项,因此乘积p不能为0 if (std::fabs(p) < 1e-9) { std::cout << "无效输入:等比数列项不能为0,乘积p不能为0" << std::endl; return 1; } // 计算中间项b:立方根 double b = std::cbrt(p); // 计算二次方程系数与判别式 double B = b - s; double C = b * b; double discriminant = B * B - 4 * C; // 判断是否存在实根(考虑浮点数精度误差) if (discriminant < -1e-9) { std::cout << "不存在满足条件的实数列" << std::endl; return 0; } // 处理判别式接近0的情况(重根) if (std::fabs(discriminant) < 1e-9) { double a = -B / 2.0; double c = (b * b) / a; std::cout << "满足条件的等比数列前三项为:" << std::fixed << std::setprecision(4) << a << ", " << b << ", " << c << std::endl; return 0; } // 计算两个可能的首项 double sqrt_d = std::sqrt(discriminant); double a1 = (-B + sqrt_d) / 2.0; double a2 = (-B - sqrt_d) / 2.0; // 计算对应第三项 double c1 = (b * b) / a1; double c2 = (b * b) / a2; // 输出结果(保留4位小数) std::cout << "满足条件的等比数列前两组解:" << std::endl; std::cout << "解1:" << std::fixed << std::setprecision(4) << a1 << ", " << b << ", " << c1 << std::endl; std::cout << "解2:" << std::fixed << std::setprecision(4) << a2 << ", " << b << ", " << c2 << std::endl; return 0; }
关键注意事项
- 立方根计算:使用
std::cbrt而非pow(p, 1.0/3),因为pow对负数输入会返回NaN,而cbrt能正确处理正负实数(例如std::cbrt(-8)返回-2) - 浮点数精度:判断
p=0或判别式是否为0时,使用极小值1e-9而非直接等于0,避免浮点数精度误差 - 等比数列有效性:计算出的
a不会为0(否则判别式会为负,已提前过滤),确保等比数列的项均非0
测试案例
输入s=14,p=64,输出:
满足条件的等比数列前两组解: 解1:2.0000, 4.0000, 8.0000 解2:8.0000, 4.0000, 2.0000
内容的提问来源于stack exchange,提问作者wienio03
相关产品推荐
相关产品推荐

