Очень хорошая общая реализация.

вопрос:Как удалить чередование битов (UnMortonizing?) имеет хороший ответ для извлечения одной из двух половин числа Мортона (только нечетные биты), но мне нужно решение, которое извлекает обе части (нечетные биты и четные биты) за как можно меньшее количество операций.

Для моего использования мне нужно было бы взять 32-битное целое число и извлечь две 16-битные целые, где один - четные биты, а другой - нечетные биты, сдвинутые вправо на 1 бит, например

input,  z: 11101101 01010111 11011011 01101110

output, x: 11100001 10110111 // odd bits shifted right by 1
        y: 10111111 11011010 // even bits

Кажется, существует множество решений, использующих сдвиги и маски с магическими числами для генерации чисел Мортона (то есть чередования битов), напримерЧередование битов по двоичным магическим числам, но я еще не нашел ничего для того, чтобы сделать обратное (то есть деинтерлейсинг).

ОБНОВИТЬ

Перечитав раздел «Восхищение Хакера», посвященный идеальным перемешкам / растасовкам, я нашел несколько полезных примеров, которые я адаптировал следующим образом:

// morton1 - extract even bits

uint32_t morton1(uint32_t x)
{
    x = x & 0x55555555;
    x = (x | (x >> 1)) & 0x33333333;
    x = (x | (x >> 2)) & 0x0F0F0F0F;
    x = (x | (x >> 4)) & 0x00FF00FF;
    x = (x | (x >> 8)) & 0x0000FFFF;
    return x;
}

// morton2 - extract odd and even bits

void morton2(uint32_t *x, uint32_t *y, uint32_t z)
{
    *x = morton1(z);
    *y = morton1(z >> 1);
}

Я думаю, что это все еще можно улучшить, как в его нынешней скалярной форме, так и за счет использования SIMD, поэтому я все еще заинтересован в лучших решениях (либо скалярных, либо SIMD).

Ответы на вопрос(5)

Ваш ответ на вопрос