Что ж, вы хотите, чтобы все биты прошли, если его 1, и ни одного, если его 0. Таким образом, вы хотите каким-то образом превратить 1 в -1 (то есть 0xffffffff), а 0 остается неизменным. Вот только -X .... так ты и делаешь ...
Y & (-X)
для каждого элемента ... работа выполнена?
Edit2: чтобы дать пример кода, вы можете сделать что-то вроде этого и избежать ветки:
int result=0;
for ( int i = 0; i < L; i++ )
{
result+=Y[i] & -(int)((X >> i) & 1);
}
Конечно, лучше всего хранить 1 и 0 в массиве целых чисел и избегать сдвигов.
Редактировать: Стоит также отметить, что если значения в Y имеют размер 16 бит, то вы можете выполнить 2 из них и операций за операцию (4, если у вас есть 64-битные регистры). Тем не менее, это означает отрицание значений X 1 на 1 в большее целое число.
то есть YVals = -4, 3 в 16-битном = 0xFFFC, 0x3 ... положить в 1 32-битный и вы получите 0xFFFC0003. Если у вас есть 1, 0 в качестве значений X, тогда вы формируете битовую маску 0xFFFF0000 и 2 вместе, и у вас есть 2 результата в 1 поразрядно, и операция.
Другое редактирование:
ЕСЛИ вам нужен код о том, как сделать 2-й метод что-то вроде , это должно сработать (Хотя оно использует неуказанное поведение, поэтому оно может работать не на каждом компиляторе ... работает на каждом компиляторе, который я '' хотя попадаюсь)
union int1632
{
int32_t i32;
int16_t i16[2];
};
int result=0;
for ( int i = 0; i < (L & ~0x1); i += 2 )
{
int3264 y3264;
y3264.i16[0] = Y[i + 0];
y3264.i16[1] = Y[i + 1];
int3264 x3264;
x3264.i16[0] = -(int16_t)((X >> (i + 0)) & 1);
x3264.i16[1] = -(int16_t)((X >> (i + 1)) & 1);
int3264 res3264;
res3264.i32 = y3264.i32 & x3264.i32;
result += res3264.i16[0] + res3264.i16[1];
}
if ( i < L )
result+=Y[i] & -(int)((X >> i) & 1);
Надеюсь, компилятор оптимизирует присвоения (Сверху головы, я не уверен, но идея может быть переработана так, чтобы они точно были), и даст вам небольшое ускорение в том, что вам теперь нужно только сделать 1 поразрядно - а не 2. Ускорение было бы незначительным, хотя ...