superskater46
superskater46

Reputation: 21

Finding a square root using only integers

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?

Upvotes: 2

Views: 3051

Answers (5)

Amit Priyadarshi
Amit Priyadarshi

Reputation: 51

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

int square_number = findSquareRootFloor(GivenValue);

int findSquareRootFloor(int number)
{
    int low = 0;
    int high = number;
    int mid = 0;
    while (low <= high)
    {
        int mid = (high + low) / 2;
        int target = mid * mid;
        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
    return high;
}

Upvotes: 0

Thure D&#252;hrsen
Thure D&#252;hrsen

Reputation: 71

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.

Upvotes: 0

SOfanatic
SOfanatic

Reputation: 5573

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

Upvotes: 0

jxh
jxh

Reputation: 70472

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.

Upvotes: 0

sashkello
sashkello

Reputation: 17871

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.

Upvotes: 2

Related Questions