Finding a square root using only integers

好久不见. 提交于 2020-01-05 00:50:06

问题


Recently, I came across a problem in someone's programming class. It asked them to compute a square root using only integers; they were to use one integer to represent the part before the decimal point and another integer to represent the part after the decimal point. The problem said that using floating point numbers was not allowed.

However, after thinking about it for some time, I can't seem to come up with a way of doing it without using floating point. I've Googled high and low and I can't seem to find an answer.

I jokingly suggested that my friend implement an FPU to do this, but he wasn't so amused.

Does anyone have any ideas about how to go about solving this?


回答1:


Let's say your original number is x.

  1. Finding part before decimal point is easy - just find the maximal number, which square is less or equal to the original number.

  2. Multiply original number by 100 and the integer part of sqrt by 10. Add 1 to it until it's less or equal to 100x. Do it n times and divide by 10^n at the end to get the final answer truncated to n decimal places.




回答2:


Assume you have an algorithm that creates two integers A and B so that the ratio A / B gives you your desired approximation to the square root to the appropriate number of decimal places. Then, the two numbers you want will be:

  • The integer part is (A - (A % B)) / B.
  • The fractional part: Let X be A % B. Then the ration X / B represents the fractional part. Then the computed fractional part is done by building the successive digits by computing (10*X - (10*X % B)) / B and setting X = (10*X % B) over and over again until you get the number of decimal places you want.

To derive the desired fraction approximation to your square root, you can compute a continued fraction for your square root.




回答3:


In pseudo-code it would be something like this:

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;
}

This answer follows the steps on calculating a square root by hand: http://www.wikihow.com/Calculate-a-Square-Root-by-Hand




回答4:


Suppose you want to compute the square root of 123.4567.

Then all you have to do is shift the decimal point far enough to the right to get an integer radicand -- in this example, four places -- and so, the following is true:

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

That is, all you need to know is how to find the square root of an integer. For this, consider the following code (in 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;

}

If you want to do away with the multiplication, you can also do this:

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;

}

These are clearly not the fastest ways to do it -- but they use integers only, and they do not rely on characteristics of particular CPUs such as word length.




回答5:


I believe a modified form of binary binary search is what will help you achieve that. Let me elaborate that in a pseudo code.

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
} 


来源:https://stackoverflow.com/questions/16532697/finding-a-square-root-using-only-integers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!