2016-10-12 4 views
0

Этот вопрос аналогичен по своему характеру: Is -!(condition) a correct way to obtain a full-bitvector from a boolean (mask-boolean)?Оптимизация Булева маска Назначение

В рамках решения HW, Я хотел бы осуществить проверку условий и последующее назначение всех «1» или «0» биты к 32bit int.

Мой код: value & ~(!(x & y) - 1). Если существует некоторое перекрытие между битами x и y, значение устанавливается равным 0, в противном случае значение остается в силе.

Мой вопрос в том, как оптимизировать это утверждение, чтобы уменьшить количество задействованных операторов. Возможно ли это использование только унарных и двоичных целых операций ! ~ &^| + - */% << >>?

Вот мой код для некоторой ссылки, он повторяет низкий порядок п биты х к длине слова:

int bitRepeat(int x, int n) { 
/* Mask desired bits, shift and OR by larger intervals each time, return repeated pattern */  

/* Check for n = 32, set a to all 1's if n != 32 */ 
int nMax = ~(!(n & 31)-1); 

/* Mask low-order n bits */ 
int maskBits = ~(~0 << n) & x; 

/* Initialize shift factors */ 
int n2 = n * 2; 
int n4 = n * 4; 
int n8 = n * 8; 
int n16 = n * 16; 

/* Shift and OR masked bits by intervals n * x {x: 1,2,4,8,16}, check for overflow at each step */ 
int overFlowMask = ~0 << 5; 
maskBits = maskBits | maskBits << n; 
maskBits = maskBits | ((maskBits << (n2)) & ~(!((n2) & overFlowMask) - 1)); 
maskBits = maskBits | ((maskBits << (n4)) & ~(!((n4) & overFlowMask) - 1)); 
maskBits = maskBits | ((maskBits << (n8)) & ~(!((n8) & overFlowMask) - 1)); 
maskBits = maskBits | ((maskBits << (n16)) & ~(!((n16) & overFlowMask) - 1)); 

return (maskBits & ~nMax) | (x & nMax); 
} 

бы реализующему unsigned данные в некоторой емкости помощи?

ответ

0

Вы можете сделать это намного проще (мы хотим заполнить целое число с n повторами битового шаблона).

unsigned int bitRepeat(unsigned int x, int n) 
{ 
    unsigned int answer = 0; 

    while(x) 
    { 
    answer |= x; 
    x <<= n; 
    } 

    return answer; 
} 

Вы должны использовать целые числа без знака, потому что переход вне MSB знакового целого числа может иметь непредсказуемые последствия. (Потому что компилятор может оптимизировать до x * = poweroftwo и установить арифметические ловушки переполнения).

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

так

int bitRepeat(int x, int n) 
{ 
    unsigned int rack = x; 

    rack = (rack << n) | rack; 
    n *= 2; 
    rack = (rack << n) | rack; 
    n *= 2; 
    rack = (rack << n) | rack; 
    n *= 2; 
    rack = (rack << n) | rack; 
    n *= 2; 
    rack = (rack << n) | rack; 

    return rack; 
} 

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

+0

Thank you. К сожалению, я не могу изменить 'int bitRepeat (int x, int n)' или использовать циклы/условные обозначения. Помогло ли хранение 'x' в контейнере' unsigned'? – sgoldburg