Skip to content

Instantly share code, notes, and snippets.

@shawnfeng0
Last active November 25, 2020 14:11
Show Gist options
  • Select an option

  • Save shawnfeng0/3c7e9a30213d69dbaa3a2830ac909505 to your computer and use it in GitHub Desktop.

Select an option

Save shawnfeng0/3c7e9a30213d69dbaa3a2830ac909505 to your computer and use it in GitHub Desktop.
template<typename T>
static inline auto RoundPowOfTwo(T n) -> decltype(n) {
uint64_t value = n;
// Fill 1
value |= value >> 1U;
value |= value >> 2U;
value |= value >> 4U;
value |= value >> 8U;
value |= value >> 16U;
value |= value >> 32U;
// Unable to round-up, take the value of round-down
if (decltype(n)(value + 1) == 0) {
value >>= 1U;
}
return value + 1;
}
static inline uint16_t RoundUpPowOfTwo(uint16_t n) {
if (n == 0) return 1;
// Avoid is already a power of 2
return RoundPowOfTwo<decltype(n)>(n - 1);
}
static inline uint16_t RoundDownPowOfTwo(uint16_t n) {
return RoundPowOfTwo<decltype(n)>(n >> 1U);
}
// EXPECT_EQ(RoundDownPowOfTwo(0), 1);
// EXPECT_EQ(RoundDownPowOfTwo(1), 1);
// EXPECT_EQ(RoundDownPowOfTwo(2), 2);
// EXPECT_EQ(RoundDownPowOfTwo(3), 2);
// EXPECT_EQ(RoundDownPowOfTwo(4), 4);
// EXPECT_EQ(RoundDownPowOfTwo(5), 4);
// EXPECT_EQ(RoundDownPowOfTwo(63), 32);
// EXPECT_EQ(RoundDownPowOfTwo(64), 64);
// EXPECT_EQ(RoundDownPowOfTwo(65), 64);
// EXPECT_EQ(RoundDownPowOfTwo(UINT16_MAX - 1), INT16_MAX + 1);
// EXPECT_EQ(RoundDownPowOfTwo(UINT16_MAX), INT16_MAX + 1);
//
// EXPECT_EQ(RoundUpPowOfTwo(0), 1);
// EXPECT_EQ(RoundUpPowOfTwo(1), 1);
// EXPECT_EQ(RoundUpPowOfTwo(2), 2);
// EXPECT_EQ(RoundUpPowOfTwo(3), 4);
// EXPECT_EQ(RoundUpPowOfTwo(4), 4);
// EXPECT_EQ(RoundUpPowOfTwo(5), 8);
// EXPECT_EQ(RoundUpPowOfTwo(63), 64);
// EXPECT_EQ(RoundUpPowOfTwo(64), 64);
// EXPECT_EQ(RoundUpPowOfTwo(65), 128);
// EXPECT_EQ(RoundUpPowOfTwo(UINT16_MAX - 1), INT16_MAX + 1);
// EXPECT_EQ(RoundUpPowOfTwo(UINT16_MAX), INT16_MAX + 1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment