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?
How deep do you project your tree to be? You could set a range of say... +/- 0.00000001 to the number to force it to an integer value.
I'm actually not certain you'll hit a number like 1.99999999 because your log2 should not lose any accuracy when calculating 2^n values (Since floating point rounds to the nearest power of 2).
Given the way floating point numbers work (crudely, mantissa * 2^exponent), then any number up to 2^127 that is a power of 2 will be exactly represented without error.
This does give a trivial but rather hacky solution - interpret the bit pattern of the floating point number as an integer, and just look at the exponent. This is David Thornley's solution above.
It is not true that any integer can be represented as a float - only those with fewer bits than the mantissa can represent. In 32bit floats, that is 23 bits worth.
This has been proposed in the comments above. Using gcc builtins:
Rewriting Todd Lehman's answer to be more generic:
Clang with
-O3
unrolls the loop:When
n
is constant, result is computed in compilation time.This is an old post but I share my one line algorithm: