LoginSignup
0
1

More than 5 years have passed since last update.

C > ビット演算 > sizedCopy()の実装 > 改良版 > unsigned long mask = (1u << size) - 1; *dst &= ~mask; *dst |= (src & mask);

Last updated at Posted at 2015-11-03

ある数値のうち、特定のビットだけを別の変数へコピーしたい。
ただし、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

0
1
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1