0

サイズ 2^x の特定の「ブロック」を新しい値に置き換える関数を作成しようとしています。

たとえば、数字が1110 1000 0010あり、ブロック 2 (最大ブロック サイズ 2^4) を に置き換えたい場合0110、 が得られ0110 1000 0010ます。110同様に、ブロック 2 を(最大ブロック サイズ 2^3) に置き換えたい場合は111 110 000 010、 、またはを取得し1111 1000 0010ます。

replace_block (value, x, blockNumber, newValue) {
    value |= ((value >> (blockNumber*x) & ~((1 << x) – 1)) | newValue) << (blockNumber*x)
}

Step by step process of what I'm trying to do with this code:
1. Shift the block we want all the way to the right
2. Mask that block with 0's
3. Mask that block again, but with the new value we want
4. Shift the block all the way back to the original position
5. Or the bits in the block with the original value

これは私がこれまでに持っているものですが、正しいとは思いません。

注: 一番右のブロックはブロック 0 です。

4

1 に答える 1

2

最初にマスクが必要です。マスクは、「ブロック サイズ」幅で右ブロックにシフトされたもののセットです。

  • 1 のセット「ブロック サイズ」幅:(1<<size) - 1
  • 正しい場所にシフトされた「ブロックサイズ」幅の1のセット:((1<<size)-1) << (number*size)

最初に、置き換えられる場所のビットをクリアしてから、必要なビットを固定します。

  • マスクされたビットがクリアされた古い値:oldv & ~mask
  • 新しい値は正しい場所に移動しました:newv << (number*size)
  • 新しい値は正しい場所にシフトされ、右側の幅にマスクされます:(newv<<(number*size)) & mask
  • 古いビットがクリアされ、新しい値が挿入されます:(oldv&~mask) | ((newv<<(number*size))&mask)

したがって、必要なコードは次のとおりです。

    mask=(((1<<size)-1)<<(number*size));
    result=((oldv&~mask)|((newv<<(number*size))&mask));

テストプログラム:

    #include <stdio.h>

    void printbits(int n) {
        unsigned int i = 1<<(sizeof(n) * 8 - 1);
        while (i > 0) {
            if (n & i)
                 printf("1");
            else
                 printf("0");
            i >>= 1;
        }
    }

    int main(void) {

        int size,number,mask,oldv,newv,result;

        size=4;number=2;oldv=0;newv=15;
        mask=(((1<<size)-1)<<(number*size));
        result=((oldv&~mask)|((newv<<(number*size))&mask));
        printf("\nsize   = %d\nnumber = %d",size,number);
        printf("\noldv   = "); printbits(oldv);
        printf("\nnewv   = "); printbits(newv);
        printf("\nmask   = "); printbits(mask);
        printf("\nomask  = "); printbits(oldv&~mask);
        printf("\nnmask  = "); printbits((newv<<(number*size))&mask);
        printf("\nresult = "); printbits(result);
        printf("\n");

        size=4;number=2;oldv=~0;newv=0;
        mask=(((1<<size)-1)<<(number*size));
        result=((oldv&~mask)|((newv<<(number*size))&mask));
        printf("\nsize   = %d\nnumber = %d",size,number);
        printf("\noldv   = "); printbits(oldv);
        printf("\nnewv   = "); printbits(newv);
        printf("\nmask   = "); printbits(mask);
        printf("\nomask  = "); printbits(oldv&~mask);
        printf("\nnmask  = "); printbits((newv<<(number*size))&mask);
        printf("\nresult = "); printbits(result);
        printf("\n");

        size=3;number=2;oldv=0;newv=7;
        mask=(((1<<size)-1)<<(number*size));
        result=((oldv&~mask)|((newv<<(number*size))&mask));
        printf("\nsize   = %d\nnumber = %d",size,number);
        printf("\noldv   = "); printbits(oldv);
        printf("\nnewv   = "); printbits(newv);
        printf("\nmask   = "); printbits(mask);
        printf("\nomask  = "); printbits(oldv&~mask);
        printf("\nnmask  = "); printbits((newv<<(number*size))&mask);
        printf("\nresult = "); printbits(result);
        printf("\n");

        size=3;number=2;oldv=~0;newv=0;
        mask=(((1<<size)-1)<<(number*size));
        result=((oldv&~mask)|((newv<<(number*size))&mask));
        printf("\nsize   = %d\nnumber = %d",size,number);
        printf("\noldv   = "); printbits(oldv);
        printf("\nnewv   = "); printbits(newv);
        printf("\nmask   = "); printbits(mask);
        printf("\nomask  = "); printbits(oldv&~mask);
        printf("\nnmask  = "); printbits((newv<<(number*size))&mask);
        printf("\nresult = "); printbits(result);
        printf("\n");

        size=4;number=4;oldv=0xAAAAAAAA;newv=0x15;
        mask=(((1<<size)-1)<<(number*size));
        result=((oldv&~mask)|((newv<<(number*size))&mask));
        printf("\nsize   = %d\nnumber = %d",size,number);
        printf("\noldv   = "); printbits(oldv);
        printf("\nnewv   = "); printbits(newv);
        printf("\nmask   = "); printbits(mask);
        printf("\nomask  = "); printbits(oldv&~mask);
        printf("\nnmask  = "); printbits((newv<<(number*size))&mask);
        printf("\nresult = "); printbits(result);
        printf("\n");

        size=5;number=3;oldv=0xAAAAAAAA;newv=0x15;
        mask=(((1<<size)-1)<<(number*size));
        result=((oldv&~mask)|((newv<<(number*size))&mask));
        printf("\nsize   = %d\nnumber = %d",size,number);
        printf("\noldv   = "); printbits(oldv);
        printf("\nnewv   = "); printbits(newv);
        printf("\nmask   = "); printbits(mask);
        printf("\nomask  = "); printbits(oldv&~mask);
        printf("\nnmask  = "); printbits((newv<<(number*size))&mask);
        printf("\nresult = "); printbits(result);
        printf("\n");

        return 0;
    }

そして結果:

    size   = 4
    number = 2
    oldv   = 00000000000000000000000000000000
    newv   = 00000000000000000000000000001111
    mask   = 00000000000000000000111100000000
    omask  = 00000000000000000000000000000000
    nmask  = 00000000000000000000111100000000
    result = 00000000000000000000111100000000

    size   = 4
    number = 2
    oldv   = 11111111111111111111111111111111
    newv   = 00000000000000000000000000000000
    mask   = 00000000000000000000111100000000
    omask  = 11111111111111111111000011111111
    nmask  = 00000000000000000000000000000000
    result = 11111111111111111111000011111111

    size   = 3
    number = 2
    oldv   = 00000000000000000000000000000000
    newv   = 00000000000000000000000000000111
    mask   = 00000000000000000000000111000000
    omask  = 00000000000000000000000000000000
    nmask  = 00000000000000000000000111000000
    result = 00000000000000000000000111000000

    size   = 3
    number = 2
    oldv   = 11111111111111111111111111111111
    newv   = 00000000000000000000000000000000
    mask   = 00000000000000000000000111000000
    omask  = 11111111111111111111111000111111
    nmask  = 00000000000000000000000000000000
    result = 11111111111111111111111000111111

    size   = 4
    number = 4
    oldv   = 10101010101010101010101010101010
    newv   = 00000000000000000000000000010101
    mask   = 00000000000011110000000000000000
    omask  = 10101010101000001010101010101010
    nmask  = 00000000000001010000000000000000
    result = 10101010101001011010101010101010

    size   = 5
    number = 3
    oldv   = 10101010101010101010101010101010
    newv   = 00000000000000000000000000010101
    mask   = 00000000000011111000000000000000
    omask  = 10101010101000000010101010101010
    nmask  = 00000000000010101000000000000000
    result = 10101010101010101010101010101010
于 2013-10-15T03:22:34.167 に答える