Last active
November 25, 2020 14:11
-
-
Save shawnfeng0/3c7e9a30213d69dbaa3a2830ac909505 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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