In the C++ standard libraries I found only a floating point log method. Now I use log to find the level of an index in a binary tree ( floor(2log(index))
).
Code (C++):
int targetlevel = int(log(index)/log(2));
I am afraid that for some of the edge elements (the elements with value 2^n) log will return n-1.999999999999 instead of n.0. Is this fear correct? How can I modify my statement so that it always will return a correct answer?
You can use this method instead:
Note: this will modify index. If you need it unchanged, create another temporary int.
The corner case is when index is 0. You probably should check it separately and throw an exception or return an error if index == 0.
This function determines how many bits are required to represent the numeric interval: [0..maxvalue].
By subtracting 1 from the result, you get
floor(log2(x))
, which is an exact representation oflog2(x)
whenx
is a power of 2.xyy-1
00-1
110
221
321
432
532
632
732
843
This function I wrote here
If you just want a fast integer log2 operation, the following function
mylog2()
will do it without having to worry about floating-point accuracy:The code above also has a small test harness so you can check the behaviour:
It will return
UINT_MAX
for an input value of 0 as an indication of an undefined result, so that's something you should check for (no valid unsigned integer will have a logarithm that high).By the way, there are some insanely fast hacks to do exactly this (find the highest bit set in a 2's complement number) available from here. I wouldn't suggest using them unless speed is of the essence (I prefer readability myself) but you should be made aware that they exist.
This isn't standard or necessarily portable, but it will in general work. I don't know how efficient it is.
Convert the integer index into a floating-point number of sufficient precision. The representation will be exact, assuming the precision is sufficient.
Look up the representation of IEEE floating-point numbers, extract the exponent, and make the necessary adjustment to find the base 2 log.