C#使用来自" Bits"的二进制运算构建整数值。

时间:2015-05-30 17:40:57

标签: c# binary integer-arithmetic

我有一个字节数组,实际上是像这样的二进制值

byte[] buf = new byte[] { 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

二进制表示为1111 11100xFF = 00xF0 = 1)。

需要从中构建的整数或字节的值为0xFE(254)。

我考虑过将buf转换为10 s的字符串,然后再转换为整数,但必须有更优雅的方法来完成二进制操作

已知完美地执行此操作的Pascal代码是(使用字符串):

  if NumberOfBytes > 0  then begin    // there was a response
     for c := Length(Str) downto 1 do begin
        Ch := Str[c];
        if (ord(ch) AND 2) = 0 then begin
           Sin := Sin + '0';
        end else begin
           Sin := Sin + '1';
        end;
        INC(Teller);
        if (Teller mod 8) = 0 then begin
            N := BinaryStrToByte(Sin);
            Edit2.Text := Edit2.Text + ByteHex(N) + ' ' ;
            Sin := '';
        end;
     end;

由于行为的某些差异,C代码似乎也没有移植到C#:

for(bytes = 0; bytes < len; bytes++)
 {
   newByte=0;
   for(bits=0; bits<8; bits++)
   {
     newByte >>= 1;
    if(inBuf[0]==0xff) 
    {
      newByte |= 0x80;
    }
   }
   pBuf[bytes]=newByte;
 }

我希望有效地遍历原始数组,然后将真正的二进制01放入intbyte,具体取决于我是否{{}在当前位置输入1}}或0xF0

3 个答案:

答案 0 :(得分:1)

这可能会起到作用:

public static void Main()
{
    byte[] buf = new byte[] { 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
    byte result = 0;
    foreach(var b in buf.Reverse())
    {
        result <<= 1;
        if(b == 0xFF) result |= 1;
    }
    Console.WriteLine(result);
}

答案 1 :(得分:1)

具有最少量分支(和LINQ调用)的方法:

byte result = 0x00;
foreach(byte b in buf) {
    result >>= 0x01;
    byte bs = b;
    bs <<= 0x07;
    result |= bs;
}

此代码假设eac字节的最低有效位确定0(如果0xf0=1111 0000)是1(在0xff=1111 1111的情况下)应该加入。

Mono C#Interactive shell中的演示:

csharp> byte[] buf = new byte[] { 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
csharp> byte result = 0x00;
csharp> foreach(byte b in buf) {
      >     result >>= 0x01;
      >     byte bs = b;
      >     bs <<= 0x07;
      >     result |= bs;
      > }
csharp> result.ToString("X");
"FE"

答案 2 :(得分:0)

这是一个更通用的LINQ解决方案:

将字节转换为位的方法(在本例中表示为布尔值)

public static IEnumerable<Boolean> BytesToBooleans(IEnumerable<Byte> bytes)
{
    if (bytes == null)
        throw new ArgumentNullException("bytes");

    return bytes
        .Select(b =>
            {
                if (b == 0xF0)
                    return false;
                if (b == 0xFF)
                    return true;
                throw new ArgumentException();
            });
}

将布尔值解释为从最低位开始的位的方法:

public static IEnumerable<Byte> BooleansAsBitsFromLowest(this IEnumerable<Boolean> bits)
{
    if (bits == null)
        throw new ArgumentNullException("bits");

    Int32 bitsInByte = 0;
    Byte curByte = 0;

    foreach (var bit in bits)
    {
        var mask = (Byte)(bit ?
            0x1 : 0x0);

        mask = (Byte)(mask << bitsInByte);

        curByte |= mask;
        bitsInByte++;

        if (bitsInByte == 8)
        {
            yield return curByte;
            curByte = 0;
            bitsInByte = 0;
        }
    }

    if (bitsInByte != 0)
        yield return curByte;
}

以下是用法:

byte[] buf = new byte[] { 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

var bytesFromBits = BytesToBooleans(buf)
    .BooleansAsBitsFromLowest();

foreach (var resultingByte in bytesFromBits)
{
    Console.WriteLine(resultingByte.ToString("X2"));
}