[c#] 바이트에서 특정 비트 가져 오기

나는 바이트, 특히 다른 장치에서 보낸 UDP를 통해 들어온 바이트 배열에서 한 바이트가 있습니다. 이 바이트는 장치에있는 8 개의 릴레이의 켜짐 / 꺼짐 상태를 저장합니다.

해당 바이트에서 특정 비트의 값을 어떻게 얻습니까? 이상적으로는 확장 방법이 가장 우아하게 보이고 bool을 반환하는 것이 가장 의미가 있습니다.

public static bool GetBit(this byte b, int bitNumber)
{
    //black magic goes here
}



답변

쉬운. 비트 AND를 사용하여 숫자를 비트 이동으로 저렴하게 계산할 수있는 2 ^ bitNumber 값과 비교합니다.

//your black magic
var bit = (b & (1 << bitNumber-1)) != 0;

편집 : 설명이없는 유사한 답변이 많기 때문에 조금 더 자세히 추가하려면 :

비트 AND는 AND 조인을 사용하여 각 숫자를 비트별로 비교하여 해당 위치의 첫 번째 비트와 두 번째 비트가 모두 설정된 비트 조합 인 숫자를 생성합니다. 다음은 비트 AND의 연산을 보여주는 “니블 (nibble)”의 AND 논리의 논리 행렬입니다.

  0101
& 0011
  ----
  0001 //Only the last bit is set, because only the last bit of both summands were set

귀하의 경우에는 귀하가 전달한 숫자를 찾고자하는 비트 만있는 숫자와 비교합니다. 네 번째 비트를 찾고 있다고 가정 해 보겠습니다.

  11010010
& 00001000
  --------
  00000000 //== 0, so the bit is not set

  11011010
& 00001000
  --------
  00001000 //!= 0, so the bit is set

비교하고자하는 숫자를 생성하는 비트 시프 팅은 정확히 들리는 것입니다. 비트 세트로 표현 된 숫자를 취하고 특정 자리 수만큼 해당 비트를 왼쪽 또는 오른쪽으로 이동합니다. 이것들은 이진수이고 각 비트는 오른쪽의 것보다 2의 거듭 제곱이 더 크므로 왼쪽으로 비트 이동은 이동 된 각 위치에 대해 한 번 숫자를 두 배로 늘리는 것과 같습니다. 2 ^ x. 귀하의 예에서 네 번째 비트를 찾고 다음을 수행합니다.

       1 (2^0) << (4-1) ==        8 (2^3)
00000001       << (4-1) == 00001000

이제 어떻게 이루어 졌는지, 낮은 수준에서 무슨 일이 일어나고 있는지, 왜 작동하는지 알 수 있습니다.


답변

Josh의 대답을 읽고 이해하는 것이 좋지만 Microsoft가이 목적으로 제공 한 클래스 인 System.Collections.BitArray 를 사용하는 것이 더 행복 할 것입니다 . 모든 버전의 .NET Framework에서 사용할 수 있습니다.


답변

public static bool GetBit(this byte b, int bitNumber) {
   return (b & (1 << bitNumber)) != 0;
}

해야한다고 생각합니다.


답변

그것을하는 또 다른 방법 🙂

return ((b >> bitNumber) & 1) != 0;


답변

이것은 0.1 밀리 초보다 빠르게 작동합니다.

return (b >> bitNumber) & 1;


답변

BitArray 클래스를 사용 하고 OP가 제안하는대로 확장 메서드를 만듭니다.

public static bool GetBit(this byte b, int bitNumber)
{
    System.Collections.BitArray ba = new BitArray(new byte[]{b});
    return ba.Get(bitNumber);
}


답변

이 시도:

return (b & (1 << bitNumber))>0;