Search code examples
logarithmsqrt

Finding log2() using sqrt()


This is an interview question I saw on some site.

It was mentioned that the answer involves forming a recurrence of log2() as follows:

double log2(double x )
{
if ( x<=2 ) return 1;
 if ( IsSqureNum(x) )
   return log2(sqrt(x) ) * 2;
 return log2( sqrt(x) ) * 2 + 1; // Why the plus one here.
}

as for the recurrence, clearly the +1 is wrong. Also, the base case is also erroneous. Does anyone know a better answer? How is log() and log10() actually implemented in C.


Solution

  • Perhaps I have found the exact answers the interviewers were looking for. From my part, I would say it's little bit difficult to derive this under interview pressure. The idea is, say you want to find log2(13), you can know that it lies between 3 to 4. Also 3 = log2(8) and 4 = log2(16),

    from properties of logarithm, we know that log( sqrt( (8*16) ) = (log(8) + log(16))/2 = (3+4)/2 = 3.5

    Now, sqrt(8*16) = 11.3137 and log2(11.3137) = 3.5. Since 11.3137<13, we know that our desired log2(13) would lie between 3.5 and 4 and we proceed to locate that. It is easy to notice that this has a Binary Search solution and we iterate up to a point when our value converges to the value whose log2() we wish to find. Code is given below:

    double Log2(double val)
    {
        int lox,hix;
        double rval, lval;
        hix = 0;
        while((1<<hix)<val)
            hix++;
        lox =hix-1;
        lval = (1<<lox) ;
        rval = (1<<hix);
        double lo=lox,hi=hix;
       // cout<<lox<<" "<<hix<<endl;
        //cout<<lval<<" "<<rval;
        while( fabs(lval-val)>1e-7)
        {
            double mid = (lo+hi)/2;
            double midValue = sqrt(lval*rval);
    
            if ( midValue > val)
            {
                 hi = mid;
                 rval = midValue;
            }
            else{
                lo=mid;
                lval = midValue;
            }
        }
        return lo;
    
    }