2012-09-19 5 views
3

현재 BitConverter를 사용하여 부호있는 int 내에서 두 개의 unsigned shorts를 패키징하고 있습니다. 이 코드는 다른 값에 대해 수백만 번 실행되며 코드가 더 최적화 될 수 있다고 생각합니다. 여기에 내가 현재하고있는 일이있다. 코드는 C#/NET이라고 가정 할 수있다.재구성을 위해 부호있는 int를 부호없는 short 두 개로 변환합니다.

// to two unsigned shorts from one signed int: 
int xy = 343423; 
byte[] bytes = BitConverter.GetBytes(xy); 
ushort m_X = BitConverter.ToUInt16(bytes, 0); 
ushort m_Y = BitConverter.ToUInt16(bytes, 2); 

// convet two unsigned shorts to one signed int 
byte[] xBytes = BitConverter.GetBytes(m_X); 
byte[] yBytes = BitConverter.GetBytes(m_Y); 
byte[] bytes = new byte[] { 
    xBytes[0], 
    xBytes[1], 
    yBytes[0], 
    yBytes[1], 
}; 
return BitConverter.ToInt32(bytes, 0); 

이렇게 비트 시프트하면 배열을 구성하는 오버 헤드를 피할 수 있습니다. 그러나 나 자신의 삶에 대해 나는 올바른 교대 조작이 무엇인지 알 수 없다. 첫 번째 애처로운 시도는 다음 코드와 관련이 있습니다.

int xy = 343423; 
const int mask = 0x00000000; 
byte b1, b2, b3, b4; 
b1 = (byte)((xy >> 24)); 
b2 = (byte)((xy >> 16)); 
b3 = (byte)((xy >> 8) & mask); 
b4 = (byte)(xy & mask); 
ushort m_X = (ushort)((xy << b4) | (xy << b3)); 
ushort m_Y = (ushort)((xy << b2) | (xy << b1)); 

누군가 나를 도울 수 있습니까? 이동하기 전에 상단 및 하단 바이트를 가릴 필요가 있다고 생각합니다. 내가 본 예제 중 일부는 type.MaxValue 또는 음수 12와 같이 임의의 숫자로 뺄셈을 포함하고 있는데, 이는 꽤 혼란 스럽습니다.

** 업데이트 **

위대한 응답 감사합니다.

// 34ms for bit shift with 10M operations 
// 959ms for BitConverter with 10M operations 

static void Main(string[] args) 
    { 
     Stopwatch stopWatch = new Stopwatch(); 

     stopWatch.Start(); 
     for (int i = 0; i < 10000000; i++) 
     { 
      ushort x = (ushort)i; 
      ushort y = (ushort)(i >> 16); 
      int result = (y << 16) | x; 
     } 
     stopWatch.Stop(); 
     Console.WriteLine((int)stopWatch.Elapsed.TotalMilliseconds + "ms"); 

     stopWatch.Start(); 
     for (int i = 0; i < 10000000; i++) 
     { 
      byte[] bytes = BitConverter.GetBytes(i); 
      ushort x = BitConverter.ToUInt16(bytes, 0); 
      ushort y = BitConverter.ToUInt16(bytes, 2); 

      byte[] xBytes = BitConverter.GetBytes(x); 
      byte[] yBytes = BitConverter.GetBytes(y); 
      bytes = new byte[] { 
       xBytes[0], 
       xBytes[1], 
       yBytes[0], 
       yBytes[1], 
      }; 
      int result = BitConverter.ToInt32(bytes, 0); 
     } 
     stopWatch.Stop(); 
     Console.WriteLine((int)stopWatch.Elapsed.TotalMilliseconds + "ms"); 


     Console.ReadKey(); 
    } 

답변

5

가장 간단한 방법은 2 개 교대를 사용하여 작업을 수행하는 것입니다 : ideone에

int xy = -123456; 
// Split... 
ushort m_X = (ushort) xy; 
ushort m_Y = (ushort)(xy>>16); 
// Convert back... 
int back = (m_Y << 16) | m_X; 

데모 : link 여기에 벤치 마크 테스트 결과입니다.

+0

광산보다 더 비 겼습니다. +1 – spender

+0

'ushort'로 캐스팅 할 때 부호 확장 비트를 삭제하기 때문에'uint' 로의 캐스트는 필요하지 않습니다. – LukeH

+0

@LukeH 네 말이 맞아, 나는 불필요한 던지기를 해답을 편집했다. – dasblinkenlight

0
int xy = 343423; 
ushort low = (ushort)(xy & 0x0000ffff); 
ushort high = (ushort)((xy & 0xffff0000) >> 16); 
int xxyy = low + (((int)high) << 16); 
관련 문제