我的平方根函数不能为某些数字提供准确的结果

时间:2016-09-16 23:12:01

标签: c++

我需要编写一个为课程作业设置正方形数字的函数。它计算数字的平方根,如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;
 }

1 个答案:

答案 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';
}