Вот решение, которое работает в постоянное время:
Вы можете вычислить позицию первого 1 бита x с помощью (int) (log (x) / log (2)).
Кроме того, вы можете вычислить число конечных нулей x с помощью хитрого трюка, показанного здесь: http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup
Следовательно, ваша программа может выглядеть примерно так:
int x, y;
int lookuptable[32] = { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25,
17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26,
12, 18, 6, 11, 5, 10, 9 };
int tail_x = lookuptable[(((x & -x) * 0x077CB531U)) >> 27];
int size_y = (int)(log(y) / log(2)) + 1;
if (tail_x - size_y <= 0) {
x <<= size_y - tail_x + 1;
} else {
x >>= tail_x - size_y - 1;
}
x |= y;
Теперь x содержит результат добавления y к x, как указано в OP. Обратите внимание, что для 32-битных компьютеров вам необходимо внести небольшие изменения.