바이트에서 특정 비트 가져 오기
나는 바이트, 특히 다른 장치에서 보낸 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;
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;
이것은 0.1 밀리 초보다 빠르게 작동합니다.
return (b >> bitNumber) & 1;
방법은 비트 AND와 함께 다른 바이트를 사용하여 대상 비트를 마스킹하는 것입니다.
여기서는 "0"이 최상위 비트이고 "7"이 가장 작은 클래스의 규칙을 사용했습니다.
public static class ByteExtensions
{
// Assume 0 is the MSB andd 7 is the LSB.
public static bool GetBit(this byte byt, int index)
{
if (index < 0 || index > 7)
throw new ArgumentOutOfRangeException();
int shift = 7 - index;
// Get a single bit in the proper position.
byte bitMask = (byte)(1 << shift);
// Mask out the appropriate bit.
byte masked = (byte)(byt & bitMask);
// If masked != 0, then the masked out bit is 1.
// Otherwise, masked will be 0.
return masked != 0;
}
}
아래 코드를 시도하십시오. 다른 게시물과 다른 점은 마스크 ( field
)를 사용하여 여러 비트를 설정 / 얻을 수 있다는 것입니다 . 예를 들어 4 번째 비트의 마스크는 1 << 3 또는 0x10 일 수 있습니다.
public int SetBits(this int target, int field, bool value)
{
if (value) //set value
{
return target | field;
}
else //clear value
{
return target & (~field);
}
}
public bool GetBits(this int target, int field)
{
return (target & field) > 0;
}
** 예 **
bool is_ok = 0x01AF.GetBits(0x10); //false
int res = 0x01AF.SetBits(0x10, true);
is_ok = res.GetBits(0x10); // true
[Flags]
enum Relays : byte
{
relay0 = 1 << 0,
relay1 = 1 << 1,
relay2 = 1 << 2,
relay3 = 1 << 3,
relay4 = 1 << 4,
relay5 = 1 << 5,
relay6 = 1 << 6,
relay7 = 1 << 7
}
public static bool GetRelay(byte b, Relays relay)
{
return (Relays)b.HasFlag(relay);
}
참고 URL : https://stackoverflow.com/questions/4854207/get-a-specific-bit-from-byte
'IT story' 카테고리의 다른 글
Java 8에서 UTC + 0 날짜를 얻는 방법은 무엇입니까? (0) | 2020.09.10 |
---|---|
iOS : NSUserDefaults에서 부울 사용 (0) | 2020.09.10 |
Symfony2 컨트롤러에서 JSON 응답을 어떻게 보낼 수 있습니까? (0) | 2020.09.10 |
C #에서 Windows Forms 양식을 닫는 Esc 단추 (0) | 2020.09.10 |
Linux 커널은 어떻게 자체적으로 컴파일 할 수 있습니까? (0) | 2020.09.10 |