Why floor and ceil functions giving different values when applied on a log function result in c++

855 views Asked by At

Below is the program I've written to find the exponent of 6, but I this its giving wrong output or I may be wrong somewhere, I'm unable to figure out here.

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
    ll t;
    cin>>t;
    cout<<log(t)/log(6)<<"\n";
    cout<<floor(log(t)/log(6))<<"\n";
    cout<<ceil(log(t)/log(6));
    return 0;
}

Input:-

216

Output:-

3

3

4

Since 216 can be written as 6*6*6, so whether there is ceil or floor the output should be 3 in all three cases.

Answering to my own question, this problem can be solved by setting small precision(here up to 2 decimal digits), below is the program for the same.

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    cout<<log(t)/log(6)<<"\n";
    cout<<floor((floor(log(t)/log(6)*100.0)/100.0))<<"\n";
    cout<<ceil((floor(log(t)/log(6)*100.0)/100.0));
    return 0;
}
2

There are 2 answers

0
eerorika On BEST ANSWER

The log function - like most floating point calculations - is imprecise. There is often tiny amount of error in the result. In your case, you did not get the exact 3, but some value slightly greater than 3. When you apply ceil or floor to such imprecise result, you may increase or reduce the amount of the error up to a whole number. In this case you increased the error by ceiling the result from nearly correct integer to exactly following integer).

2
Bathsheba On

If you want to find the exponent of an integer with respect to a given radix, then repeated division and checking the remainder is a good starting point. There are faster ways (related to exponentation by squaring) which you could investigate if you want to squeeze out more performance.

The problem is that using the ratio of two log calls and truncating that to an int is bound to give you an inexact answer since the result of a log most likely cannot be represented exactly as a floating point value, and the log function itself may not recover the best floating point value possible (neither the C++ standard nor IEEE754 insist on that).

Finally, on #define ll long long, don't do that. It only serves to obfuscate. And #include<bits/stdc++.h> is not portable C++.