#include #include /*************************************************** * Smallest power of two greater than or equal to n * * Write a function that returns the smallest * non-negative integer m such that * * 2^m >= n. * * For example, * * n = 42 * * has the binary representation * * 00000000000000000000000000101010. * * The powers of two surrounding 42 are * * 32 = 2^5 * 64 = 2^6. * * Since * * 32 < 42 <= 64, * * the function returns * * 6. * * Notice that the function returns the EXPONENT, * not the power of two itself. * * * USING BIT SHIFTING * * We can generate successive powers of two by * starting with * * 1 = 2^0 * * and repeatedly shifting its single 1 bit to the * left: * * 00000000000000000000000000000001 2^0 * 00000000000000000000000000000010 2^1 * 00000000000000000000000000000100 2^2 * 00000000000000000000000000001000 2^3 * 00000000000000000000000000010000 2^4 * ... * * Each left shift multiplies the value by 2. * * At the same time, we count the number of shifts. * When the power of two becomes greater than or * equal to n, that count is the exponent we want. * * * EXAMPLES * * n result * ---------------- * 1 0 because 2^0 = 1 * 2 1 because 2^1 = 2 * 3 2 because 2^2 = 4 * 4 2 because 2^2 = 4 * 5 3 because 2^3 = 8 * 16 4 because 2^4 = 16 * 17 5 because 2^5 = 32 * * Thus, when n itself is a power of two, the * corresponding exponent is returned. * * Mathematically, for n > 0, this function is * calculating * * ceil(log_2(n)). * * * THE VALUE n == 0 * * There is no unique smallest non-negative exponent * m satisfying * * 2^m >= 0, * * because m = 0 already satisfies the inequality. * * For this function, we define the result to be 0 * when n == 0. Thus both n == 0 and n == 1 return 0. ***************************************************/ // Function declarations int main(); unsigned int power_of_2_greater_or_equal( std::uint64_t n ); // Function definitions int main() { for ( std::uint64_t k{ 10 }; k < 1100; k += 13 ) { std::cout << k << ": " << power_of_2_greater_or_equal( k ) << std::endl; } return 0; } /*************************************************** * power_of_2_greater_or_equal * * Returns the smallest non-negative integer m such * that * * 2^m >= n. * * For n == 0, the function returns 0. ***************************************************/ unsigned int power_of_2_greater_or_equal( std::uint64_t n ) { unsigned int exponent{ 0 }; for ( std::uint64_t power_of_2{ 1 }; power_of_2 != 0; power_of_2 <<= 1 ) { if ( power_of_2 >= n ) { return exponent; } ++exponent; } // If the loop ends, n is greater than 2^63. // The next required power of two would be 2^64, // which cannot be represented by std::uint64_t. return 64; }