Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement square root and exponentiation on arbitrary length numbers?

I'm working on new data type for arbitrary length numbers (only non-negative integers) and I got stuck at implementing square root and exponentiation functions (only for natural exponents). Please help.

I store the arbitrary length number as a string, so all operations are made char by char.

Please don't include advices to use different (existing) library or other way to store the number than string. It's meant to be a programming exercise, not a real-world application, so optimization and performance are not so necessary.

If you include code in your answer, I would prefer it to be in either pseudo-code or in C++. The important thing is the algorithm, not the implementation itself.

Thanks for the help.

like image 535
Tom Pažourek Avatar asked Dec 25 '10 22:12

Tom Pažourek


People also ask

How do you write square root in pseudocode?

Here is the pseudo code: x = 1 repeat 10 times: x = (x + n / x) / 2 return x.

How do you find the square root of a number in CPP?

The sqrt() function in C++ returns the square root of a number. This function is defined in the cmath header file. Mathematically, sqrt(x) = √x .

How do you find the square root of a binary number?

Below are the steps to find the square root of an integer (N) using binary search. Step 1: Let Left = 1 , and Right = N . Step 2.1: Middle = (Left + Right ) / 2 , Square = Middle * Middle . Step 2.2: If (Square == N) , return Middle as the answer.


2 Answers

Square root: Babylonian method. I.e.

function sqrt(N):
    oldguess = -1
    guess = 1
    while abs(guess-oldguess) > 1:
        oldguess = guess
        guess = (guess + N/guess) / 2
    return guess

Exponentiation: by squaring.

function exp(base, pow):
    result = 1
    bits = toBinary(powr)
    for bit in bits:
        result = result * result
        if (bit):
            result = result * base
    return result

where toBinary returns a list/array of 1s and 0s, MSB first, for instance as implemented by this Python function:

def toBinary(x):
    return map(lambda b: 1 if b == '1' else 0, bin(x)[2:])

Note that if your implementation is done using binary numbers, this can be implemented using bitwise operations without needing any extra memory. If using decimal, then you will need the extra to store the binary encoding.

However, there is a decimal version of the algorithm, which looks something like this:

function exp(base, pow):
    lookup = [1, base, base*base, base*base*base, ...] #...up to base^9
     #The above line can be optimised using exp-by-squaring if desired

    result = 1
    digits = toDecimal(powr)
    for digit in digits:
        result = result * result * lookup[digit]
    return result
like image 105
Artelius Avatar answered Sep 30 '22 22:09

Artelius


Exponentiation is trivially implemented with multiplication - the most basic implementation is just a loop,

result = 1;    
for (int i = 0; i < power; ++i) result *= base;

You can (and should) implement a better version using squaring with divide & conquer - i.e. a^5 = a^4 * a = (a^2)^2 * a.

Square root can be found using Newton's method - you have to get an initial guess (a good one is to take a square root from the highest digit, and to multiply that by base of the digits raised to half of the original number's length), and then to refine it using division: if a is an approximation to sqrt(x), then a better approximation is (a + x / a) / 2. You should stop when the next approximation is equal to the previous one, or to x / a.

like image 44
zeuxcg Avatar answered Oct 01 '22 00:10

zeuxcg