数字的平方根...精确到n精度

时间:2013-09-15 12:46:09

标签: c++ algorithm numerical-methods

The method as found on Wikipedia

The method as found on Wikipedia

我无法理解上述方法。有人可以解释一下吗?我已经做了一些代码,但它仅限于一些硬编码精度,似乎消耗了太多的计算机资源。

R = 0.00001
INPUT N
WHILE R*R != N
        R = R + 0.00001
ENDWHILE
PRINT R

对于高达n精度的数字的平方根,算法或C ++代码是什么? 如果需要,可以从用户处获取。

2 个答案:

答案 0 :(得分:0)

有些算法更适合计算机评估。我在20世纪60年代的问题中学到了这个问题,作为一种使用过程而不是长分割手动计算平方根的方法。

在计算结果的第n个数字时,目标是找到最大的前缀字符串,使得该平方小于或等于输入的前2n个数字。

关键的基本想法是(a+b)^2 = a^2 + b^2 + 2ab。在算法中,a是到目前为止的部分结果,b是新数字。它通过在输入中移动结果中一个生成数字的两个位置来计算方形中的因子100和根中的10个因子。

在追加数字p之前,让d成为部分结果。我们已从输入中减去p^2。我们还需要减去d^2 + 2pd,以保持减去新部分结果的平方。等价地,减去d(2p+d)。我们已将p加倍,追加d,然后乘以d。在继续下一步之前,我们还需要加倍d

答案 1 :(得分:0)

这是一段C ++代码,虽然它不是任意精度,但它可能对您有用。它比您的BASIC代码更接近完整的解决方案:

#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <climits>

const unsigned g_unPlaces = 8;

int main(int argc, char** argv)
{
  if (argc != 2)
  {
    std::cerr << "USAGE: " << *argv << " NUMBER" << std::endl;
    return 1;
  }

  std::vector<unsigned> vecInteger;
  std::vector<unsigned> vecDecimal;
  char *pDecimal = strchr(argv[1], '.');

  // Read integer part of NUMBER
  if (pDecimal == NULL) pDecimal = argv[1] + strlen(argv[1]);
  if ((pDecimal - argv[1]) % 2) vecInteger.push_back(0);
  for (char *pCurrent = argv[1]; pCurrent < pDecimal; ++pCurrent)
  {
    int nValue = *pCurrent - '0';
    if (nValue >= 10 || nValue < 0)
    {
      std::cerr << "Error: Invalid character in input!" << std::endl;
      return 1;
    }
    vecInteger.push_back((unsigned) nValue);
  }

  // Read decimal part of NUMBER
  if (*pDecimal != '\0')
  {
    for (++pDecimal; *pDecimal != '\0'; ++pDecimal)
    {
      if (*pDecimal == '.')
      {
        std::cerr << "Error: Multiple decimals in input!" << std::endl;
        return 1;
      }

      int nValue = *pDecimal - '0';
      if (nValue >= 10 || nValue < 0)
      {
        std::cerr << "Error: Invalid character in input!" << std::endl;
        return 1;
      }
      vecDecimal.push_back((unsigned) nValue);
    }
    if (vecDecimal.size() % 2) vecDecimal.push_back(0);
  }

  const unsigned unInteger = vecInteger.size();
  const unsigned unDecimal = vecDecimal.size();

  std::vector<unsigned> vecValues;

  unsigned x, y = 0, c = 0, p = 0;
  for (unsigned i = 0; i < g_unPlaces; ++i)
  {
    if (2*i < unInteger-1)
    {
      c = (c*100 - y*100) + vecInteger[i*2]*10 + vecInteger[i*2+1];
    }
    else if (2*i < unInteger+unDecimal-1)
    {
      c = (c*100 - y*100) + vecDecimal[i*2-unInteger]*10
          + vecDecimal[i*2+1-unInteger];
    }
    else
    {
      c = c*100 - y*100;
    }

    if (c == 0) break;

    y = 0;
    for (x = 1; x < 10; ++x)
    {
      unsigned temp = x*(20*p + x);
      if (temp > c) { --x; break; }
      y = temp;
    }

    p = 10*p + x;
    vecValues.push_back(x);
  }

  // Write the result
  for (unsigned i = 0; i < unInteger/2; ++i)
  {
    std::cout << vecValues[i];
  }
  std::cout << '.';
  for (unsigned i = unInteger/2; i < vecValues.size(); ++i)
  {
    std::cout << vecValues[i];
  }
  std::cout << std::endl;

  return 0;
}

至于理解算法的帮助,最好的方法是从乞讨开始,逐步完成每一步。尝试使用像4,16和64这样的小值。用一张纸和一支铅笔逐步完成算法,并记下每一步的部分。

如果您的目标只是计算N精度的数字,那么您可能会更好地使用已经制作的解决方案,更改您的问题,因此您不需要N精度或查看其他一些注释/答案。