C#을 사용하여 24 비트 (리틀 엔디안, 2의 보수) 값을 나타내는 3 바이트의 배열을 정수로 변환하는 빠른 방법이 있습니까? 이 문제를 어떻게 해결해야합니까?C#에서 24 비트, 리틀 엔디안, 2의 보수 값을 정수로 변환하는 모범 사례?
감사합니다.
C#을 사용하여 24 비트 (리틀 엔디안, 2의 보수) 값을 나타내는 3 바이트의 배열을 정수로 변환하는 빠른 방법이 있습니까? 이 문제를 어떻게 해결해야합니까?C#에서 24 비트, 리틀 엔디안, 2의 보수 값을 정수로 변환하는 모범 사례?
감사합니다.
아직 아무도 제안하지 않은 사람이 BitConverter
입니다. 별도의 변수에 3 바이트는 한 가정 : 또는
var data = new byte[]
{
byte0 & 0x80 == 0 ? 0 : 0xFF, byte0, byte1, byte2
};
return BitConverter.ToInt32(data, 0);
또는 :
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;
내가 한 번 Bitconverter의 리틀 엔디안 자연 점화되었다. 대체 접근법은 다음과 같습니다. 추 신 : 형식은 리틀 엔디안이 아니며, 다른 방식은 MSB 우선입니다!. 또한 나는 비트 mannually 출력 포맷을 시도하지만 실패
출력 :
INT32 (MSB 우선/좌) ======= 에 ======= 시험 24 비트 기대 값 : 8,388,607 Bit24ToInt32 시험 : 8,388,607 기대 값 : -1 Bit24ToInt32 시험 : -1 기대 값 : -8388607 Bit24ToInt32 시험 : -8388607 기대 값 : 6,147,053 Bit24ToInt32 시험 : 6,147,053
======= 16 비트에서 Int32로 테스트 (MSB First/Left) = ====== 기대 값 : 32767 Bit16ToInt32 시험 : 32767 기대 값 : -1 Bit16ToInt32 시험 : -1 기대 값 : -32767 Bit16ToInt32 시험 : -32767 기대 값 : 24,045 Bit16ToInt32 테스트 : 24,045
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;
}
}
}
는 당신이 다른 엔디안과 아키텍처를 통해 제대로 작동 할 경우 당신은 수동으로'BitConverter.IsLittleEndian'을 테스트하고 그에 따라'data' 배열의 순서를 조정해야합니다. 처음부터 직접 또는 수동으로 작업하는 것보다 훨씬 복잡합니다. – LukeH
좋은 캐치, 루크. XBox (및 Mono)는 빅 엔디안 아키텍처를 지원합니다. –
설명해 주셔서 감사합니다. – Evan