开发者

Best practice for converting 24bit, little endian, two's complement values to ints in C#?

Is there a quick, built in way, using C# to convert an array of three bytes representing a 24bit (little endian, two's complement) value to an int? How should I go about this?

开发者_高级运维Thanks!


I'm surprised no one has suggested BitConverter yet. Assuming you have the three bytes in separate variables:

var data = new byte[]
{
  byte0 & 0x80 == 0 ? 0 : 0xFF, byte0, byte1, byte2
};
return BitConverter.ToInt32(data, 0);

or alternatively:

var data = new byte[] { byte0, byte1, byte2, 0x00 };
return BitConverter.ToInt32(data, 0) >> 8;


int converted = ((bytes[2] << 24) | (bytes[1] << 16) | (bytes[0] << 8)) >> 8;


I got burned by the little endian nature of the Bitconverter once. Here is an alternate approach: PS: The format is not little endian, its the other way around with MSB first!. Also i tried to format the output a bit mannually but failed

Output:

=======Test 24 bit to Int32 (MSB First/Left)======= Expected: 8388607 Bit24ToInt32 Test: 8388607 Expected: -1 Bit24ToInt32 Test: -1 Expected: -8388607 Bit24ToInt32 Test: -8388607 Expected: 6147053 Bit24ToInt32 Test: 6147053

Expected: -6147053 Bit24ToInt32 Test: -6147053

=======Test 16 bit to Int32 (MSB First/Left)======= Expected: 32767 Bit16ToInt32 Test: 32767 Expected: -1 Bit16ToInt32 Test: -1 Expected: -32767 Bit16ToInt32 Test: -32767 Expected: 24045 Bit16ToInt32 Test: 24045

Expected: -24045 Bit16ToInt32 Test: -24045

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BitExperiments
{
    class Program
    {
        static void Main(string[] args)
        {
            //Test 16bit to Int32(MSB First/Left)
            Console.WriteLine("=======Test 24 bit to Int32 (MSB First/Left)=======");
            Dictionary<int,byte[]> cases = new Dictionary<int,byte[]>();
            byte[] bytearr;
            int expectedResult;

            bytearr = new byte[] { 0x7F, 0xFF, 0xFF };
            expectedResult= 8388607;//Max
            cases.Add(expectedResult,bytearr);

            bytearr = new byte[] { 0xFF, 0xFF, 0xFF };
            expectedResult = (-1);//Mid
            cases.Add(expectedResult,bytearr);

            bytearr = new byte[] { 0x80, 0x00, 0x01 };
            expectedResult = (-8388607);//Min
            cases.Add(expectedResult,bytearr);

            bytearr = new byte[] { 0x5D, 0xCB, 0xED };
            expectedResult= 6147053;//Random 
            cases.Add(expectedResult,bytearr);

            bytearr = new byte[] { 0xA2, 0x34, 0x13 };
            expectedResult= (-6147053);//Random  inverted
            cases.Add(expectedResult,bytearr);

            foreach (var value in cases)
            {
                Console.WriteLine("Expected: {0} \t\t Bit24ToInt32 Test:  {1}", value.Key, Bit24ToInt32(value.Value));
            }

            Console.WriteLine("===================================================");
            Console.WriteLine();
            //Test 16bit to Int32(MSB First/Left)
            Console.WriteLine("=======Test 16 bit to Int32 (MSB First/Left)=======");
            cases.Clear();

            bytearr = new byte[] { 0x7F, 0xFF };
            expectedResult = 32767;//Max
            cases.Add(expectedResult, bytearr);

            bytearr = new byte[] { 0xFF, 0xFF };
            expectedResult = (-1);//Mid
            cases.Add(expectedResult, bytearr);

            bytearr = new byte[] { 0x80, 0x01 };
            expectedResult = (-32767);//Min
            cases.Add(expectedResult, bytearr);

            bytearr = new byte[] { 0x5D, 0xED };
            expectedResult = 24045;//Random 
            cases.Add(expectedResult, bytearr);

            bytearr = new byte[] { 0xA2, 0x13 };
            expectedResult = (-24045);//Random  inverted
            cases.Add(expectedResult, bytearr);

            foreach (var value in cases)
            {
                Console.WriteLine("Expected: {0} \t\t Bit16ToInt32 Test:  {1}", value.Key, Bit16ToInt32(value.Value));
            }
            Console.WriteLine("===================================================");
            Console.ReadLine();
        }
        private static int Bit24ToInt32(byte[] byteArray)
        {
            int result = (  
                 ((0xFF & byteArray[0]) << 16) |  
                 ((0xFF & byteArray[1]) << 8) |   
                 (0xFF & byteArray[2])  
               );  
             if ((result & 0x00800000) > 0) 
             {  
               result = (int)((uint)result|(uint)0xFF000000);  
             } 
             else 
             {  
               result = (int)((uint)result & (uint)0x00FFFFFF);  
             }  
            return result; 
        }

        private static int Bit16ToInt32(byte[] byteArray) {
            int result = (
              ((0xFF & byteArray[0]) << 8) |
               (0xFF & byteArray[1])
              );
            if ((result & 0x00008000) > 0) {
                  result = (int) ((uint) result | (uint) 0xFFFF0000);

            } else {
                  result = (int) ((uint) result & (uint) 0x0000FFFF);
            }
            return result;
          }         
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜