使用二分法计算平方根无法提升精度的技术求助
二分法计算平方根精度问题排查
问题根源
你的代码存在三个核心问题,导致无法输出更高精度的结果:
- cout默认输出精度限制:C++的
cout默认仅显示6位有效数字,即便long double存储了更高精度的数值,输出时也会被自动截断。 - diff计算逻辑漏洞:仅当
mid*mid < val时才更新diff值,当mid*mid > val时diff保留之前的旧值,可能错误触发终止条件,导致迭代提前结束。 - pow函数精度损失:使用的
pow()是double版本,返回值为double类型,与long double比较时会丢失精度,无法满足高tolerance的精度需求。
修复方案
针对上述问题,可通过以下几点修改代码:
- 引入
<iomanip>头文件,用于设置输出精度; - 用
fabsl()计算mid*mid - val的绝对值,确保diff始终为当前迭代的真实差值; - 替换
pow()为powl(),使用long double版本的幂函数生成阈值; - 设置
cout为固定小数格式,并指定输出精度为tolerance位。
修改后的代码
#include <iostream> #include <math.h> #include <iomanip> // 用于设置输出精度 using namespace std; int main() { int val, tolerance; cout << "输入要求平方根的数字,以及精度位数tolerance(终止条件为10^-tolerance):" << endl; cout << "请输入数字,再输入精度位数:" << endl; cin >> val >> tolerance; if (val < 0) return 0; long double low = 0, high = val; long double mid = (low + high) / 2; long double diff; const long double threshold = powl(10, -tolerance); // 用powl生成long double阈值 while (true) { diff = fabsl(mid * mid - val); // 计算差值绝对值,确保diff始终正确 if (diff <= threshold) { cout << fixed << setprecision(tolerance); // 设置固定小数格式与精度 cout << val << "的平方根为:" << mid << endl; break; } else if (mid * mid > val) { high = mid; } else { low = mid; } mid = (low + high) / 2; // 统一更新mid,减少重复代码 } return 0; }
关键说明
fixed << setprecision(tolerance)会强制cout输出tolerance位小数,比如tolerance=15时,会完整显示15位小数;fabsl()是long double版本的绝对值函数,确保处理大数值时精度不丢失;powl()生成long double类型的阈值,避免double转long double带来的精度损失;- 重构循环逻辑,将mid的更新移到循环末尾,简化代码结构。
内容的提问来源于stack exchange,提问作者jitender
相关产品推荐
相关产品推荐

