2012-07-03 2 views
0

비트 필드에 위치 정보를 저장하는 방법 (필드의 OR 또는 다른 순서)은 어떻게됩니까?주문 종속적 비트 필드

배경 : 게임 엔진의 일부를 쓰면서 지난 밤에 내 머리에 튀어 나왔습니다. 우리가 색을 기술하려고한다고 가정하자. 그리고 그것의 일부로 우리는 기술자 (그리고 그들의 순서)에있는 색을 가지고있다. A | R | G | B가있다 그 필드를 사용하여,

None = 0x0 
A = 0x1 
R = 0x2 
G = 0x4 
B = 0x8 

그러나 :

RGBA 
BGRA 

다음의 플래그

지원되는 색상을 설명하는 데 사용 할 수 있습니다 : 예를 들어 우리는 오늘날 대부분의 그래픽 카드에 다음과 같은 색상 주문이 B | G | R | A과 같은 것. 위치 종속성을 추가하는 데 사용할 수있는 플래그 및/또는 연산을 어떻게 설계 하시겠습니까? 배타성 추가를위한 보너스 표시 (예 : 위치 1에 RG을 가질 수 없음) 및 유틸리티 (이 시나리오에서는 가능할 수도있는 영리한 방법).

+0

저는 실제로 이것을하는 것을 고려하고 있지 않습니다. 단지 흥미 롭다고 생각했습니다. '조기 최적화'에 대한 언급이 없습니다. –

+0

* order *를 인코딩하려면 가장 자연스러운 것은 IMHO가 순열을 열거하고 그 수를 사용하는 것입니다. 가장 자연스러운 열거 형은 혼합 기수 (Yates-shuffle과 결합 된 것일 수도 있습니다) – wildplasser

+0

@wildplasser입니다. 그래서'(A * 2^0) XOR (R * 3^1) XOR G * 4^2) XOR (B * 5^3)'? –

답변

0

각 플래그를 추가하기 전에 각 고유 플래그에 필요한 비트 수만큼 비트 필드를 이동할 수 있습니다. 다음의 플래그가 사용된다 : 리틀 엔디안 시스템에서

None = 0x0 
A = 0x1 
R = 0x2 
G = 0x4 
B = 0x8 
Shift = 0x4 
Mask = 0xF (A | R | G | B) 

는 각 OR 전에 Shift (<<) 왼쪽으로 이동합니다. 0 << x = 0이기 때문에 None에 남은 교대를 제거 할 수 있습니다.

A1 = A 
A1R2 = (A1 << Shift) | R 
A1R2G3 = (A1R1 << Shift) | G 
A1R2G3B4 = (A1R1G3 << Shift) | B 

B1 = B 
B1G2 = (B1 << Shift) | G 
B1G2R3 = (B1G2 << Shift) | R 
B1G2R3A4 = (B1G2R3 << Shift) | A 

Mask으로 반복해서 바로 그것을 이동 것입니다 각각의 위치 (리틀 엔디안) 및 AND을 추출하려면 원래의 예를 감안할. 현재 값이 None에이를 때까지이 작업을 반복하면 역순으로 처리됩니다.

let cur = the bit field we want to check 
loop until cur = None: 
    let val = cur AND Mask 
    emit the name of val 
    let cur = cur >> Shift 

이 독점을 제공하지 않습니다 (당신은 쉽게 AAGB을 할 수있는)하고 어떤 유틸리티를 가지고처럼은 보이지 않는다.