2009-09-18 8 views
7

바이트 쌍을 가져 와서 단락을 출력하고 단락을 가져 와서 바이트 쌍을 출력해야합니다. 이러한 목적을 위해 내가 고안 한 기능은 다음과 같습니다.짧은 문자와 바이트 사이를 변환하는 좋은 방법은 무엇입니까?

static short ToShort(short byte1, short byte2) 
{ 
    short number = (short)byte2; 
    number <<= 4; 
    number += (short)byte1; 
    return number; 
} 
static void FromShort(short number, out byte byte1, out byte byte2) 
{ 
    byte byte2 = (byte)(number >> 4); 
    short tempByte = (short)byte2 << 4; 
    byte byte1 = (byte)(number - tempByte); 
} 

나는 정확하다고 생각하지만 확실하지 않습니다. 이것이 올바른 방법이 아니라면 무엇입니까? 프레임 워크에서 이미이 작업을 수행 할 수있는 방법이 있습니까?

+0

현재 8 비트,하지 4. –

+0

흥미로운 물건을 이동해야합니다 ToShort에서 byte1은 MSB (즉 왼쪽에있는 것)이고, FromShort에서 byte1은 LSB (즉 오른쪽에있는 것)입니다. 나는 내 대답에 이것을 바꿨다 ;-p –

답변

16

짧은 버전 (또한 8 비트 대신 4 이동) : 당신이 바이트를 가지고 ... 바이트을하려면

static short ToShort(short byte1, short byte2) 
{ 
    return (byte2 << 8) + byte1; 
} 

static void FromShort(short number, out byte byte1, out byte byte2) 
{ 
    byte2 = (byte)(number >> 8); 
    byte1 = (byte)(number & 255); 
} 
+0

나는 이것에 도움이 될 것입니다. – RCIX

+4

짧은, 던지기로 ToShort 메서드에서 코드를 래핑했다 그냥 내가 알게 될 줄 알았는데 ... – RCIX

+0

이 컴파일되지 않습니다 ... 왜 그렇게 많은 upvotes? short + short는 정수 연산자로 해석되며 암시 적으로 int를 short로 캐스팅 할 수 없습니다. – Assimilater

5

바이트는 4가 아닌 8 비트이므로 시프트가 해제됩니다. 두 번째 함수에서도 지역 변수를 선언 했으므로 의도 한대로 out 매개 변수를 작성하지 않게됩니다. 가능한 경우 비트 연산 (&, |~)으로 제한하면 더 명확하거나 더 좋습니다.

static short ToShort(byte byte1, byte byte2) 
{ 
    return (short) ((byte2 << 8) | (byte1 << 0)); 
} 

static void FromShort(short number, out byte byte1, out byte byte2) 
{ 
    byte2 = (byte) (number >> 8); 
    byte1 = (byte) (number >> 0); 
} 

0으로 왼쪽과 오른쪽으로 시프트하는 것은 불필요합니다. 나는 그것들을 대칭을 위해 넣었습니다. 또한, 개인적으로 나는 비트 연산 산술 감기와 스킵 쓰기 헬퍼 함수를 ​​배우는 것이 좋습니다. IMHO와 같이 근본적인 것으로 세부 사항을 숨길 필요가 없습니다.

+1

이것은 내가 권하고 싶은 유일한 해결책이다. – Goot

+1

이것은 서명 된 단문에 맞는 유일한 해결책입니다 – Yiping

+0

이것은 받아 들여진 대답이어야합니다 ... 실제로 컴파일됩니다 ... – Assimilater

4

을; 당신의 변화가 꺼져 있고, | 더 직관적 인 것 :

static short ToShort(byte byte1, byte byte2) 
{ // using Int32 because that is what all the operations return anyway... 
    return (short)((((int)byte1) << 8) | (int)byte2); 
} 
static void FromShort(short number, out byte byte1, out byte byte2) 
{ 
    byte1 = (byte)(number >> 8); // to treat as same byte 1 from above 
    byte2 = (byte)number; 
} 
+0

바이트를 가져가는 것은 실제로 실수였습니다 ... 좋은 팁, 감사합니다! – RCIX

+0

일반적으로 바이트 1이 아닌 바이트 2를 비트 시프트하려고합니다. 그래서 뭔가가 : return (short) ((byte2 << 8) | byte1); –

+0

int 캐스트는 불필요하지만 어쨌든 일어날 일을 보여줍니다. (그리고 이것이 여러분이 주석의 의미라고 생각합니다.) +1 – Assimilater

0

System.BitConverter

+1

배열의 오버 헤드는 항상 신경 쓰지 않는 한 그것이 리틀 엔디안인지 빅 엔디안인지에 대한 제어권을가집니다. –

+0

@Marc Gravell 제어권을 가진 한, BE와 LE를 모두 처리하기 위해서는 로직을 사용해야합니다. 배열을 뒤집는 것과 똑같은가요? 하지만 배열은 약간의 오버 헤드가 될 것이라고 생각합니다 ... – TJB

+1

그런 논리를 넣었을 때, 비트 연산을 사용하고 모든 문제를 피할 수 있었을 것입니다 ... 만약 당신이 바이트 변환을 다루고 있다면, 약간의 수학을 배우는 것이 가장 좋은 해결책 일 것입니다; -p –

27

사용 BitConverter

short number = 42; 
byte[] numberBytes = BitConverter.GetBytes(number); 
short converted = BitConverter.ToInt16(numberBytes); 
+0

흠, 이런 생각은하지 않았지만 지금은 Ates의 붕괴를 좋아합니다. 감사! – RCIX

+2

당신에게 가장 적합한 것은 무엇이든! 이와 같은 방법을 사용하는 것의 장점은 다른 프로젝트에서이 코드를 사용해야하는 경우 라이브러리와 공유 코드를 작성하는 대신에 바로이 코드를 사용할 수 있다는 것입니다. 또한 BitConverter에 대한 지식이 있으면 다른 개발자도 BitConverter에 대한 지식을 다시 얻을 수 있습니다. 개인적으로 우리는 공유 할 바이트 변환에 대한 래퍼 코드를 사용 했었지만 내장 된 것들을 사용하는 것보다는 관리하기가 번거롭고 복잡했습니다. 그러나 진지하게, 당신에게 가장 잘 맞는 것을 사용하십시오.) – TJB

+1

마음에 ac/C++ 프로그래머로서 나는 누군가가 간단한 비트 시프트 및/또는 연산을 수행하는 것이 부담 스러울 것이라고 바보를 느낀다. 그러나 'Bit []'를 생성하고 'BitConverter'가 구현되어 '바이트 []'나중에 바보 같아 .... – Assimilater