ある数値のうち、特定のビットだけを別の変数へコピーしたい。
ただし、sprintf()などの関数は使えないとする。
try1 (独自実装)
以下のような実装をした。
void sizedCopy(int size, int src, unsigned long *dst)
{
int chk;
int loop;
int shift;
shift = size - 1;
chk = (0x01 << (size - 1)); // from MSB to LSB
for(loop=0; loop<size; loop++) {
if ( (src & chk) > 0 ) {
*dst |= (0x01 << shift);
} else {
*dst &= ~(0x01 << shift);
}
chk = (chk >> 1);
shift--;
}
}
テスト込みの実装は
http://ideone.com/K9GS5L
#include <stdio.h>
void sizedCopy(int size, int src, unsigned long *dst)
{
int chk;
int loop;
int shift;
shift = size - 1;
chk = (0x01 << (size - 1)); // from MSB to LSB
for(loop=0; loop<size; loop++) {
if ( (src & chk) > 0 ) {
*dst |= (0x01 << shift);
} else {
*dst &= ~(0x01 << shift);
}
chk = (chk >> 1);
shift--;
}
}
int main(void) {
unsigned long ulval = 0;
sizedCopy(3, 0x35, &ulval); // 0x35 = 110101b
printf("0x%X", ulval); // answer: 0x5
return 0;
}
結果
Success time: 0 memory: 2156 signal:0
0x5
上記の関数の改良版を複数回呼ぶことにより、一つの変数に複数の数値情報を入れる、という処理を検討中。
改良版 (yohhoyさん)
yohhoyさんに教えていただいた(ずっと)改良版。
unsigned long mask = (1u << size) - 1;
*dst &= ~mask;
*dst |= (src & mask);
自分の理解力が足りなかったので、上記動作のメモを記す。
mask =
については、size=3の時は 111bとなるようにしている (=1000b - 1)。
&= ~
にて該当ビットを全部OFF
|=
にて srcのうち該当サイズ分だけ( & mask )ビットが1となっている部分をON