仅使用整数查找平方根

时间:2013-05-13 23:18:08

标签: integer square-root

最近,我在某人的编程课中遇到了一个问题。它要求他们仅使用整数计算平方根;它们使用一个整数来表示小数点前的部分,使用另一个整数来表示小数点后的部分。问题是不允许使用浮点数。

然而,在考虑了一段时间之后,我似乎无法想出一种不使用浮点的方法。我用Google搜索了高低,似乎无法找到答案。

我开玩笑地建议我的朋友实施FPU来做这件事,但他并不那么开心。

有没有人对如何解决这个问题有任何想法?

5 个答案:

答案 0 :(得分:2)

假设您的原始号码为x

  1. 在小数点前查找部分很简单 - 只需找到最大数字,哪个方格小于或等于原始数字。

  2. 将原始数字乘以100,将sqrt的整数部分乘以10.向其中加1,直到它小于或等于100x。执行n次并在结尾处除以10^n,以将最终答案截断为n小数位。

答案 1 :(得分:0)

假设您有一个算法可以创建两个整数AB,以便比率A / B为您提供所需的平方根近似值到适当的小数位数。然后,您想要的两个数字将是:

  • 整数部分为(A - (A % B)) / B
  • 小数部分:让XA % B。然后定量X / B代表小数部分。然后计算的小数部分是通过计算(10*X - (10*X % B)) / B并反复设置X = (10*X % B)来构建连续数字来完成的,直到得到你想要的小数位数。

为了得到平方根的所需分数近似值,您可以计算平方根的连续分数。

答案 2 :(得分:0)

在伪代码中,它将是这样的:

int whole_ans = sqrt(num); //stores final answer integer part
int dec_ans; //stores final answer decimal part

int num_of_decimals = x   //x is equal to the number of decimal places you want the answer to be
int targetNum = (num - (whole_ans^2)) * 100;  //initialize target to residual * 100
int currAns = whole_ans; //initialize target to residual of num - the answer so far

for(int i=0;i<x;i++)
{
    x = get_next_digit(targetNum,currAns));
    dec_ans = append(dec_ans, x);  //append the new found digit to the right of the current decimal answer
    targetNum = (targetNum - (currAns * 20 + x) * x) * 100; //update target number to be residual + 2 zero digits
    currAns = append(currAns,dec_ans) //append the decimal part of the answer to the current total answer so far

}

func get_next_digit(targetNum,currAns)
{
int attempt=0;
int i=0;
   while(attempt <= targetNum)
   {
       i++;
       attempt = (20 * currAns + i) * i;
   }
i--;
return i;
}

这个答案遵循手动计算平方根的步骤:http://www.wikihow.com/Calculate-a-Square-Root-by-Hand

答案 3 :(得分:0)

假设您要计算123.4567的平方根。

然后你所要做的就是将小数点移到右边足够远的地方得到一个整数基数 - 在这个例子中,有四个位置 - 所以,以下是真的:

sqrt(123.4567) = (1/100) * sqrt(1234567)

也就是说,您需要知道的是如何找到整数的平方根。为此,请考虑以下代码(在C中):

unsigned int int_sqrt (unsigned int n) {

    unsigned int result = 0;
    unsigned int count  = 1;

    for (; count*count <= n; count += 1) {

        result = result + 1;

    }

    return result;

}

如果你想取消乘法,你也可以这样做:

unsigned int int_sqrt (unsigned int n) {

    unsigned int result = 0;
    unsigned int odd    = 1;
    unsigned int oddsum = 1;

    while (oddsum <= n) {

        result = result + 1;
        odd = odd + 2;
        oddsum = oddsum + odd;

    }

    return result;

}

这些显然不是最快的方法 - 但它们只使用整数,并且它们不依赖于特定CPU的特征,如字长。

答案 4 :(得分:0)

我相信二进制二进制搜索的修改形式将帮助您实现这一目标。 让我在伪代码中详细说明。

int square_number = findSquareRootFloor(GivenValue);

findSquareRootFloor( int number)
{
   int low = 0;
   int high = number;
   while (low <=high)
   {
       int mid = number /2; // note use integer division
       target = searchedValue * searchedValue`enter code here`;
       if (target > number)
           high = mid-1;
       else if (target < number)
           low = mid +1;
       else 
       { // exact match
          return mid;
       }
   }

   // if we have come here mid stores the floor of the square root
}