2008-10-07 6 views
4

그래서, bitfields. 특히, 큰 비트 필드. 나는 비트 필드의 개별 값을 조작하는 방법을 이해하지만 어떻게 내가 같은 대형 세트에이 일에 대해 갈 것이라고하는 말 : 수행C#의 비트 필드

uint[] bitfield = new uint[4] { 0x0080000, 0x00FA3020, 0x00C8000, 0x0FF00D0 }; 

나는 데 특정 문제가 좌우하고있는 변화 전체 배열을 통해.

uint[4] { 0x0008000, 0x000FA302, 0x000C800, 0x00FF00D }; 

지금 여기 (지나치게) 간단한 알고리즘이 날 즉석에서 코드를을 writting입니다 (같은 것을 볼 수 있습니다 내가 위의 배열에 >> 4을 한 경우에 그래서 예를 들어, 내가 끝낼 것) :

이러한 종류의 데이터로 작업하기 쉽습니다.

답변

2

BitArray가 bool을 내부적으로 사용한다고 생각합니까? 부울 값을 사용하여 API 측면에서 비트를 표현하지만 후드에서는 int []를 사용한다고 생각합니다.

+0

어쨌든, 여전히 내가해야 할 일을 지원하지 않습니다. –

+0

일산화탄소 : 어쨌든, 당신은 무지하고 있습니다. – leppie

+1

BitArray를 "현재 시프트"를 기억하고 모든 액세스에서 해당 값을 더하거나 뺍니다 유형으로 래핑하는 방법은 어떻습니까? –

0

확장 방법을 사용하여, 당신이 할 수 있습니다 :

public static class BitArrayExtensions 
{ 
    public static void DownShift(this BitArray bitArray, int places) 
    { 
     for (var i = 0; i < bitArray.Length; i++) 
     { 
      bitArray[i] = i + places < bitArray.Length && bitArray[i + places]; 
     } 
    } 

    public static void UpShift(this BitArray bitArray, int places) 
    { 
     for (var i = bitArray.Length - 1; i >= 0; i--) 
     { 
      bitArray[i] = i - places >= 0 && bitArray[i - places]; 
     } 
    } 
} 

불행하게도, 나는 시프트 연산자를 오버로드 할 수있는 방법을 마련 할 수 없었다. (주로 때문에 BitArray 밀봉된다.)

intuint S 또는 S를 조작하고자하는 경우에는 /로 비트 삽입 BitArray로부터 비트들을 추출하기위한 확장 방법을 만들 수있다. (BitArray에는 int의 배열을 사용하는 컨스트럭터가 있지만 그만큼 멀리까지 이동합니다.)

1

나는 그것을 할 수있는 가장 좋은 방법이 있는지 확실하지 않습니다에 적용 할 수 있다고 생각하지만,이 범위는 0에있을 변화를 제약 (일할 수 -31

public static void ShiftLeft(uint[] bitfield, int shift) { 

     if(shift < 0 || shift > 31) { 
      // handle error here 
      return; 
     } 

     int len = bitfield.Length; 
     int i = len - 1; 
     uint prev = 0; 

     while(i >= 0) { 
      uint tmp  = bitfield[i]; 
      bitfield[i] = bitfield[i] << shift; 
      if(i < len - 1) { 
       bitfield[i] |= (uint)(prev & (1 >> shift) - 1) >> (32 - shift); 
      } 
      prev = tmp; 

      i--; 
     } 

    } 

    public static void ShiftRight(uint[] bitfield, int shift) { 

     if(shift < 0 || shift > 31) { 
      // handle error here 
      return; 
     } 
     int len = bitfield.Length; 
     int i = 0; 
     uint prev = 0; 

     while(i < len) { 
      uint tmp  = bitfield[i]; 
      bitfield[i] = bitfield[i] >> shift; 
      if(i > 0) { 
       bitfield[i] |= (uint)(prev & (1 << shift) - 1) << (32 - shift); 
      } 
      prev = tmp; 

      i++; 
     } 

    } 

PD :.이 변경, 당신은 31 비트보다 더 큰 변화를 처리 할 수 ​​있어야 조금 덜 예쁘게 만들기 위해 리팩토링,하지만 내 테스트에서, 그것은 작동하고 아무튼 될 수 있습니다. (실제로는 큰 비트 집합을 처리하기 위해 내장 된 것이 아니라면 성능 측면에서 너무 나쁘게 보입니다.)

public static void ShiftLeft(uint[] bitfield, int shift) { 

     if(shift < 0) { 
      // error 
      return; 
     } 

     int intsShift = shift >> 5; 

     if(intsShift > 0) { 
      if(intsShift > bitfield.Length) { 
       // error 
       return; 
      } 

      for(int j=0;j < bitfield.Length;j++) { 
       if(j > intsShift + 1) {  
        bitfield[j] = 0; 
       } else { 
        bitfield[j] = bitfield[j+intsShift]; 
       } 
      } 

      BitSetUtils.ShiftLeft(bitfield,shift - intsShift * 32); 
      return; 
     } 

     int len = bitfield.Length; 
     int i = len - 1; 
     uint prev = 0; 

     while(i >= 0) { 
      uint tmp = bitfield[i]; 
      bitfield[i] = bitfield[i] << shift; 
      if(i < len - 1) { 
       bitfield[i] |= (uint)(prev & (1 >> shift) - 1) >> (32 - shift); 
      } 
      prev = tmp; 

      i--; 
     } 

    } 

    public static void ShiftRight(uint[] bitfield, int shift) { 

     if(shift < 0) { 
      // error 
      return; 
     } 

     int intsShift = shift >> 5; 

     if(intsShift > 0) { 
      if(intsShift > bitfield.Length) { 
       // error 
       return; 
      } 

      for(int j=bitfield.Length-1;j >= 0;j--) { 
       if(j >= intsShift) {   
        bitfield[j] = bitfield[j-intsShift]; 
       } else { 
        bitfield[j] = 0; 
       } 
      } 

      BitSetUtils.ShiftRight(bitfield,shift - intsShift * 32); 
      return; 
     } 


     int len = bitfield.Length; 
     int i = 0; 
     uint prev = 0; 

     while(i < len) { 
      uint tmp = bitfield[i]; 
      bitfield[i] = bitfield[i] >> shift; 
      if(i > 0) { 
       bitfield[i] |= (uint)(prev & (1 << shift) - 1) << (32 - shift); 
      } 
      prev = tmp; 

      i++; 
     } 

    } 
관련 문제