Search code examples
c++algorithmfloating-pointlogarithm

Does this function compute the natural logarithm of a number with an exact precision of 3 digits?


I have the following algorithm in my textbook that should compute the natural log of a number with an exact precision of 3 digits.

#include <iostream>
#include <cmath>

double logN(double a, double li, double ls)
{
    if(a == 1)
        return 0;
    else if(fabs(li - ls) < 0.0001)

        return (li + ls) / 2;
    else if((exp(li) - a) * (exp((li + ls) / 2) - a) < 0)
        return logN(a, li, (li + ls) / 2);
    else
        return logN(a, (li + ls) / 2, ls);
}

int main()
{
    std::cout << logN(3, 0, 3) << std::endl;
    std::cout << logN(4, 0, 4) << std::endl;
    std::cout << logN(5, 0, 5) << std::endl;

    return 0;
}

This statement looks wrong to me:

else if(fabs(li - ls) < 0.0001)

For example, if I have 2 numbers: 0.9992 and 0.9996. Both numbers have the first 3 digits equal, but the difference between them is 0.0004 which is greater than 0.0001 and thus the test will fail. What am I missing?


Solution

  • This is needed in order (li + ls) / 2 to work correctly.

    For example:

    0.999 - 0.9981 = 0.0009 < 0.001
    

    but:

    (0.999 + 0.9981) / 2 = 0.99855
    

    On the other hand:

    (0.9999 + 0.9998) / 2 = 0.99985
    

    which rounds up to 1, when rounding to 3rd digit.