在c#.net中将一系列位转换为整数值的常规方法是什么?

时间:2017-04-18 19:59:03

标签: c# .net hex byte bitarray

我已经编程了很多年了,但是从来没有过多地使用按位运算或者在某种程度上甚至是字节级别处理过多的数据,直到现在。所以,请原谅我缺乏知识。

我必须处理通过套接字通信获得的流式消息帧数据。消息帧是一系列十六进制字节编码的Big Endian,我读入一个名为byteArray的字节数组。以下面的2个字节为例:

0x03 0x20

我需要的数据以前14位表示 - 这意味着我需要将前14位转换为int值。 (最后2位代表2个其他bool值)。我编写了以下代码来完成此任务:

if (BitConverter.IsLittleEndian)
{
    Array.Reverse(byteArray);
}

BitArray bitArray = GetBitArrayFromRange(new BitArray(byteArray), 0, 14);

int dataValue = GetIntFromBitArray(bitArray)

dataValue 变量最终会得到正确的结果: 800

我正在调用的两个函数在这里:

    private static BitArray GetBitArrayFromRange(BitArray bitArray, int startIndex, int length)
    {
        var newBitArray = new BitArray(length);

        for (int i = startIndex; i < length; i++)
        {
            newBitArray[i] = bitArray.Get(i);
        }

        return newBitArray;
    }

    private static int GetIntFromBitArray(BitArray bitArray)
    {
        int[] array = new int[1];

        bitArray.CopyTo(array, 0);

        return array[0];
    }

由于我在这方面缺乏经验,我的问题是:这段代码看起来是否正确/合理?或者,是否有更优选/传统的方式来实现我的需求?

谢谢!

1 个答案:

答案 0 :(得分:1)

  

&#34; dataValue变量以正确的结果结束: 800 &#34;

正确的结果实际上 200

1)00000011 00100001:是整数0x0321(所以现在跳过两位01 ...)

2)xx000000 11001000:提取最后14位(缺少2位,因此xx计为零)

3)00000000 11001000:预期14位提取的最终结果= 200

目前看起来你有一个空的(零填充)16位,你把14位。不知怎的,你放在完全相同的位置(左手侧而不是右手侧)

Original bits   : 00000011 00100001
Slots 16 bit    : XXXXXXXX XXXXXXXX
Instead of this : XX000000 11001000 //correct way
You have done   : 00000011 001000XX //wrong way

您的右侧XX为零,因此您的结果为00000011 00100000会给出 800 ,但这是错误的,因为它&# 39;不是你提取的那些特定14位的真值。

  

&#34;是否有更优选/传统的方式来完成我的工作   需要&#34;

我猜比特移位是传统方式......

解决方案(伪代码):

var myShort = 0x0321; //Short means 2 bytes
var answer = (myShort >> 2); //bitshift to right-hand side by 2 places

通过向右移动所有2个位置/插槽,你可以看到左边两个现在空的地方如何成为XX(自动为零直到你改变它们),并且通过轻推你也刚刚移除了(右边) -side)你想忽略的2位...给你正确的14位值。

PS:
关于你的代码......我没有机会测试它,但下面的逻辑似乎更适合你的GetBitArrayFromRange函数:

for (int i = 0; i < (length-1); i++)
{
    newBitArray[i] = bitArray.Get(startIndex + i);
}