C / C ++ Bit Twiddling - PullRequest
       6

C / C ++ Bit Twiddling

15 голосов
/ 25 ноября 2010

в духе graphics.stanford.edu / ~ seander / bithacks.html Мне нужно решить следующую проблему:

int x; 
int pow2; // always a positive power of 2
int sgn;  // always either 0 or 1
// ...
// ...
if(sgn == 0)
    x -= pow2;
else
    x += pow2;

Конечно, мне нужно избегать условных,Пока лучшее, что я придумал, это

x -= (1|(~sgn+1))*pow2

, но это включает в себя умножение, которого я также хотел бы избежать.Заранее спасибо.

РЕДАКТИРОВАТЬ: Спасибо всем,

x -= (pow2^-sgn) + sgn

, кажется, делает трюк!

Ответы [ 5 ]

16 голосов
/ 25 ноября 2010

Я бы попробовал

x -= (pow2 ^ (~sgn+1)) + sgn

или, как предполагает lijie в комментариях

x -= (pow2 ^ -sgn) + sgn

Если sgn равно 0, ~sgn+1 также 0так что pow2 ^ (~sgn+1) == pow2.Если sgn равно 1, (~sgn+1) равно 0xFFFFFFFF и (pow2 ^ (~sgn+1)) + sgn == -pow2.

4 голосов
/ 25 ноября 2010
mask = sgn - 1; // generate mask: sgn == 0 => mask = -1, sgn == 1 => mask = 0

x = x + (mask & (-pow2)) + (~mask & (pow2)); // use mask to select +/- pow2 for addition
2 голосов
/ 25 ноября 2010

с макушки головы:

int subMask = sgn - 1;
x -= pow2 & subMask;
int addMask = -sgn;
x += pow2 & addMask;

Никаких гарантий того, работает ли это или умно, нет, это просто случайная идея, которая пришла мне в голову.

РЕДАКТИРОВАТЬ: давайте сделаем это немного менее читабельным (он же более компактный):

x += (pow2 & -sgn) - (pow2 & (sgn-1)); 
1 голос
/ 25 ноября 2010

Можно сделать что-то вроде (по ссылке) x + = ((pow2 ^ -sgn) + sgn)

1 голос
/ 25 ноября 2010

Я бы изменил интерфейс и заменил бы умножение на левое смещение. (Используйте показатель вместо pow2)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...