我需要编写一个为课程作业设置正方形数字的函数。它计算数字的平方根,如16和25,但不能准确计算9的平方根。
以下是代码
double mysqrt (double x)
{
double low, high, mid;
此if语句决定创建一个范围以确定平方根。
if (x >= 0) {
low = 0;
high = x;
}
else {
low = x;
high = 1;
}
此语句计算中间值
mid = (high + low)/2.0;
while循环用于确定平方根。
while (abs(mid*mid - x) > 0.0001)
{
if (mid * mid > x)
high = mid;
else
low = mid;
mid = (high/2.0) + (low/2.0);
}
return mid;
}
答案 0 :(得分:1)
通常情况下,我不只是为他们做某人的功课,但我想挑战一下,通过将错误与固定的epsilon值进行比较,始终可以检测到收敛。
请记住,double
数据类型只能表示取自有限范围的值,因此比较两个结果之间的等效性可用于检测收敛,其中以任意精度执行此操作可能会导致无限迭代
此外,分配了一组可能的浮点值,使得一个值和下一个值之间的差值对于小值而言小于大值,因此如果使用epsilon,通常不适合保留它固定在一些任意“小”的值。
下面的代码执行相同的哑双元搜索,但退出条件测试重新访问前一个迭代的结果,这意味着进一步的迭代将只是反复覆盖相同的搜索状态,并且错误接近于最小可能。
通过这种方式,epsilon由double
数据类型本身以及输入自动确定。如果用某种任意精度类替换double
,那么你确实需要提供一个epsilon,否则非理性根可能会循环直到某种失败,就像内存不足一样。
#include <iostream>
#include <iomanip>
double mysqrt(double x) {
double low, high;
if(x < 1) {
if(x <= 0) return 0;
low = x;
high = 1;
} else {
low = 1;
high = x;
}
for(;;) {
const double mid = (low + high) / 2;
if(high == mid || low == mid) return mid;
if(mid * mid > x) {
high = mid;
} else {
low = mid;
}
}
}
int main() {
std::cout << std::setprecision(14) << mysqrt(3) << '\n';
}