Skip to content

Instantly share code, notes, and snippets.

@hamsham
Created November 15, 2015 08:44
Show Gist options
  • Save hamsham/43dd32377110eb80d895 to your computer and use it in GitHub Desktop.
Save hamsham/43dd32377110eb80d895 to your computer and use it in GitHub Desktop.
Power-of-2 functions (get the nearest, next, or previous power of 2).
/**
* Test of getting the next/previous powers of 2
*
* g++ -std=c++11 -Wall -Werror -Wextra -pedantic -pedantic-errors pow2.cpp -o pow2
*/
#include <iostream>
#include <sstream>
/******************************************************************************
* Power of 2 functions for unsigned integers
******************************************************************************/
inline unsigned nextPow2(unsigned n) {
if (n == 0) {
return 0;
}
--n;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
return ++n;
}
inline unsigned prevPow2(unsigned n) {
if (n == 0) {
return 0;
}
--n;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
return n - (n >> 1);
}
inline unsigned nearPow2(unsigned n) {
const unsigned pp2 = prevPow2(n);
const unsigned np2 = nextPow2(n);
const unsigned lo = n - pp2;
const unsigned hi = np2 - n;
return lo < hi ? pp2 : np2;
}
constexpr bool isPow2(unsigned n) {
return n && !(n & (n-1));
}
/******************************************************************************
* Verification function to make sure that main()'s "argv[1]" is a number
******************************************************************************/
bool inputIsNumber(char* const str) {
for (unsigned i = 0; str[i]; ++i) {
if (str[i] < '0' || str[i] > '9') {
return false;
}
}
return true;
}
int main(int argc, char** argv) {
if (argc != 2 || !inputIsNumber(argv[1])) {
std::cerr
<< "Incorrect Syntax. Try \"pow2 n\" where \"n\" is a positive number"
<< std::endl;
return -1;
}
std::istringstream converter(argv[1]);
unsigned uval;
converter >> uval;
std::cout << "You entered: " << uval << '\n';
if (isPow2(uval)) {
std::cout << uval << " is a power of 2.\n";
}
else {
std::cout << uval << " is NOT a power of 2.\n";
}
std::cout << "The next power of 2 is:\t\t" << nextPow2(uval) << '\n';
std::cout << "The nearest power of 2 is:\t" << nearPow2(uval) << '\n';
std::cout << "The previous power of 2 is:\t" << prevPow2(uval) << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment