È possibile utilizzare la tecnica di moltiplicazione multipla simile a quella descritta here. In questo modo non hai bisogno di loop.
Ad esempio con la maschera 0b10101001 == 0xA9
come sopra e dati a 8 bit abcdefgh
(con ah è 8 bit) è possibile utilizzare l'espressione basso per ricevere 0000aceh
unsigned compress_maskA9(unsigned x)
{
const unsigned mask = 0xA9;
const unsigned mask1 = mask & 0xF0;
const unsigned mask2 = mask & 0x0F;
return (((x & mask1)*0x03000000 >> 28) & 0x0C) | ((x & mask2)*0x50000000 >> 30);
}
In questo caso ci sono alcune sovrapposizioni di i 4 bit quando si moltiplicano quindi li divido in 2 parti, il primo estrae i bit a e c, quindi e eh verranno estratti nell'ultima parte.
si possono vedere i risultati confrontati con la funzione di Harold live on ideone
Se si desidera che i bit del risultato invertito è possibile modificare facilmente il numero magico di conseguenza.
unsigned compress_maskA9_reversed1(unsigned x)
{
// result: he00 | 00ca;
return (((x & 0x09)*0x88000000 >> 28) & 0x0C) | (((x & 0xA0)*0x04800000) >> 30);
}
o è possibile estrarre il 3 bit E, C e, allo stesso tempo, lasciando h separatamente a causa di alcuni pezzi di sovrapposizione:
unsigned compress_maskA9_reversed(unsigned x)
{
return ((x & 0xA8)*0x12400000 >> 29) | (x & 0x01) << 3; // result: 0eca | h000
}
Correttezza controllo: http://ideone.com/PYUkty
Per un un numero maggiore di maschere è possibile precomputare i numeri magici corrispondenti a quella maschera e memorizzarli in un array per un uso successivo.
Spiegazione
Abbiamo abcdefgh & mask1 = a0c00000
........................a0c00000
x 00000011000000000000000000000000 (magic1 = 0x03000000)
__________________________________________________________________
a0c00000........................
+ a0c00000......................... (the leading "a" bit is outside int's range so it'll be truncated
↓↓
__________________________________________________________________
r1 = acc.............................
=> (r1 >> 28) & 0x0C = 0000ac00
Allo stesso modo abcdefgh & mask2 = 0000e00h
........................0000e00h
x 01010000000000000000000000000000 (magic2 = 0x50000000)
__________________________________________________________________
0000e00h............................
+ 0000e00h..............................
↓↓
__________________________________________________________________
r2 = eh..............................
=> (r2 >> 30) = 000000eh
Pertanto
((r1 >> 28) & 0x0C) | (r2 >> 30) = 0000aceh
È necessario un ciclo se la maschera non è costante –
La maschera è costante ma ce ne sono 512 quindi .. non proprio "costante". – cen