Created
May 5, 2020 18:33
-
-
Save Eisenwave/7882185ff4d4ea42ea5c45af9fb4fd08 to your computer and use it in GitHub Desktop.
Functions for interleaving two or three numbers bitwise.
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
#ifndef UTIL_BITS_HPP | |
#define UTIL_BITS_HPP | |
#include <cstddef> | |
#include <cstdint> | |
#include <limits> | |
constexpr uint64_t ileave2(uint32_t x, uint32_t y) | |
{ | |
constexpr uint64_t MASKS_2[] = { | |
0x5555'5555'5555'5555, | |
0x3333'3333'3333'3333, | |
0x0F0F'0F0F'0F0F'0F0F, | |
0x00FF'00FF'00FF'00FF, | |
0x0000'FFFF'0000'FFFF | |
}; | |
uint64_t result = 0; | |
uint32_t *nums[] = {&x, &y}; | |
for (size_t i = 0; i < 2; ++i) { | |
uint64_t n = *nums[i]; | |
for (size_t i = 4; i != std::numeric_limits<size_t>::max(); --i) { | |
n |= n << (1 << i); | |
n &= MASKS_2[i]; | |
} | |
result |= n << (1 - i); | |
} | |
return result; | |
} | |
static_assert(ileave2(0b1111'1111, 0) == 0b1010'1010'1010'1010); | |
static_assert(ileave2(0, 0b1'1111'1111) == 0b01'0101'0101'0101'0101); | |
static_assert(ileave2(0, 0xffff'ffff) == 0x5555'5555'5555'5555); | |
static_assert(ileave2(0, ileave2(0, 0b11)) == 0b10001); | |
constexpr uint64_t ileave3(uint32_t x, uint32_t y, uint32_t z) | |
{ | |
constexpr size_t numInputs = 3; | |
constexpr uint64_t MASKS_2[] = { | |
0x9249'2492'4924'9249, | |
0x30C3'0C30'C30C'30C3, | |
0xF00F'00F0'0F00'F00F, | |
0x00FF'0000'FF00'00FF, | |
0xFFFF'0000'0000'FFFF | |
}; | |
uint64_t result = 0; | |
uint32_t *nums[] = {&x, &y, &z}; | |
for (size_t i = 0; i < numInputs; ++i) { | |
uint64_t n = *nums[i]; | |
for (size_t i = 4; i != std::numeric_limits<size_t>::max(); --i) { | |
const auto shift = (numInputs - 1) * (1 << i); | |
n |= n << shift; | |
n &= MASKS_2[i]; | |
} | |
result |= n << (numInputs - i - 1); | |
} | |
return result; | |
} | |
static_assert(ileave3(0, 0, 0b1111) == 0b001001001001); | |
static_assert(ileave3(0b1111, 0, 0) == 0b100100100100); | |
#endif // UTIL_BITS_HPP |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment