here과 비슷한 pack-by-multiplication 기술을 사용할 수 있습니다. 이렇게하면 루프가 필요 없습니다. 상기 8 비트의 데이터 abcdefgh
일부 오버랩이있는 이러한 경우 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);
}
를 얻기 위해 다음 식을 사용하여 (아 8 비트)와 같은 마스크 0b10101001 == 0xA9
와 예
곱해질 때의 4 비트를 2 부분으로 나누었습니다. 첫 번째 부분은 비트 a와 c를 추출한 다음 e와 h는 후자 부분에서 추출됩니다.
할 수 있습니다 참조는 결과의 비트가 쉽게 따라 마법의 수를 변경할 수 있습니다 반전하려면 해롤드의 기능 live on ideone
과 비교하여 그 결과.
unsigned compress_maskA9_reversed1(unsigned x)
{
// result: he00 | 00ca;
return (((x & 0x09)*0x88000000 >> 28) & 0x0C) | (((x & 0xA0)*0x04800000) >> 30);
}
아니면 인해 일부 중복 비트로 별도로 시간을두고, 동시에 3 비트 E, C 및 추출 할 수
unsigned compress_maskA9_reversed(unsigned x)
{
return ((x & 0xA8)*0x12400000 >> 29) | (x & 0x01) << 3; // result: 0eca | h000
}
정확성 확인하십시오 들어 http://ideone.com/PYUkty
더 많은 수의 마스크는 해당 마스크에 해당하는 매직 번호를 사전 계산하여 나중에 사용할 수 있도록 배열에 저장할 수 있습니다.
설명 우리는 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
마찬가지로이
abcdefgh & mask2 = 0000e00h
........................0000e00h
x 01010000000000000000000000000000 (magic2 = 0x50000000)
__________________________________________________________________
0000e00h............................
+ 0000e00h..............................
↓↓
__________________________________________________________________
r2 = eh..............................
=> (r2 >> 30) = 000000eh
따라서
((r1 >> 28) & 0x0C) | (r2 >> 30) = 0000aceh
마스크가 일정하지 않은 경우 루프가 필요합니다. –
마스크가 일정하지만 마스크가 일정하므로 512 개가 있습니다. 실제로는 "일정하지 않습니다". – cen