Ну, я не знаю ни одного способа сделать это эффективно, но обычный алгоритм «добавления с побитовыми операциями» предлагает следующий алгоритм (не тестировался):
static int tesseral_add(int x, int y)
{
int a, b;
do
{
a = x & y;
b = x ^ y;
x = a << 2; // move carry up 2 places instead of the usual 1
y = b;
} while (b != 0);
return b;
}
, который возможно зацикливаетсямного, если есть цепочки для переноса.
На самом деле, есть гораздо лучший способ сделать это.
Обратите внимание, что для z = interleave(a, -1); w = interleave(b, 0);
добавление z
и w
напрямую дает частично правильный результат, потому что любые переносы переносятся повторно (все биты "между ними" равны 1).Единственная «проблема» заключается в том, что она уничтожает координаты y.
Таким образом, чтобы добавить два тессеральных числа z = interleave(a, b); w = interleave(c, d);
, есть хороший короткий способ сделать это:
int xsum = (z | 0xAAAAAAAA) + (w & 0x55555555);
int ysum = (z | 0x55555555) + (w & 0xAAAAAAAA);
int result = (xsum & 0x55555555) | (ysum & 0xAAAAAAAA);