簡體   English   中英

從字節中獲取特定位

[英]Get a specific bit from byte

我有一個字節,特別是字節數組中的一個字節,該字節數組是通過另一設備發送的UDP傳入的。 該字節存儲設備中8個繼電器的開/關狀態。

如何獲得所述字節中特定位的值? 理想情況下,擴展方法看起來最優雅,而返回布爾值對我來說最有意義。

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

簡單。 使用按位與將您的數字與2 ^ bitNumber進行比較,該值可以通過移位來廉價地計算。

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

編輯:要添加更多的細節,因為有很多類似的答案而沒有解釋:

逐位AND使用AND聯接逐位比較每個數字,以產生一個數字,該數字是在該位置的第一位和第二位都被設置的位的組合。 這是“半字節”中AND邏輯的邏輯矩陣,顯示了按位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);
}

這比0.1毫秒的工作速度更快。

return (b >> bitNumber) & 1;

嘗試這個:

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

該方法是將另一個字節與按位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;
    }
}

試試下面的代碼。 與其他帖子的不同之處在於,您可以使用mask( 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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM