2010年9月8日水曜日

ビット単位のコピー

 あると便利かなーと思って作ってみた。
1Byteづつチェックするため速度かなり遅い。
ビットレベルの操作を広範囲に行うことはあまりないと思うからまあいいかなと。


#include <cstdio>
typedef unsigned char BYTE;
 
/*
 * @param dest コピー先バッファ
 * @param destBitPos コピー開始ビット位置
 * @param src 参照バッファ
 * @param srcBitPos 参照開始ビット位置
 * @param copyBitSize コピーするビット数
 */
void bitCopy(
  void* dest, int destBitPos,
  void* src, int srcBitPos,
  int copyBitSize )
{
  BYTE* destBin = static_cast<BYTE*>( dest ) + destBitPos/8;
  BYTE* srcBin = static_cast<BYTE*>( src ) + srcBitPos/8;
  destBitPos &= 0x7;
  srcBitPos &= 0x7;
 
  while ( copyBitSize > 0 )
  {
    int size = copyBitSize > 8 ? 8 : copyBitSize;
    size = min( 8-destBitPos, size );
    size = min( 8-srcBitPos, size );
    BYTE destMask = static_cast<BYTE>(0xFF >> (8-size)) << destBitPos;
    // trans copy
    *destBin = ((*destBin ^ (((*srcBin)>>srcBitPos)<<destBitPos)) & destMask) ^ *destBin;
 
    copyBitSize -= size;
    destBitPos += size;
    if ( destBitPos >= 8 )
    {
      destBin++;
      destBitPos -= 8;
    }
 
    srcBitPos += size;
    if ( srcBitPos >= 8 )
    {
      srcBin++;
      srcBitPos -= 8;
    }
  }
}
 
int main()
{
  int dest, src;
  src = 0xFFFF0000;
 
  dest = 0;
  bitCopy( &dest, 8, &src, 16, 13 );
  std::printf("%08x\n", dest);
 
  dest = 0;
  bitCopy( &dest, 8, &src, 12, 13 );
  std::printf("%08x\n", dest);
 
  dest = 0;
  bitCopy( &dest, 8, &src, 9, 13 );
  std::printf("%08x\n", dest);
 
  dest = 0xFFFFFFFF;
  bitCopy( &dest, 8, &src, 16, 13 );
  std::printf("%08x\n", dest);
 
  dest = 0xFFFFFFFF;
  bitCopy( &dest, 8, &src, 12, 13 );
  std::printf("%08x\n", dest);
 
  dest = 0xFFFFFFFF;
  bitCopy( &dest, 8, &src, 9, 13 );
  std::printf("%08x\n", dest);
 
  return 0;
}

[20110412]&lt;と&gt;逆にしてたのを修正。
 
output:

001fff00
001ff000
001f8000
ffffffff
fffff0ff
ffff80ff

0 件のコメント: