2013-10-15 2 views
0

크기 2^x의 특정 "블록"을 새 값으로 바꾸는 함수를 작성하려고합니다.비트 조작 - "블록"바꾸기

예를 들어 숫자가 1110 1000 0010이고 블록 2 (최대 블록 크기가 2^4)를 0110으로 바꾸려면 0110 1000 0010이 표시됩니다. 마찬가지로 블록 2를 110 (최대 블록 크기 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

+1

1,000 0,010 1,110 들면 : 블록 수는 2^4의 블록 크기를 갖는 우측 0부터 시작하면 (16 비트)이면 블록 2는 0110으로 대체되는 XXXX 1000 0010이고 2^3 (8) 블록 크기의 경우 블록 2는 111 XXX 000 010이어야하지만 예에서 블록 1을 대체해야합니다. 111 010 010 010 그래서 110 번 블록을 오른쪽 블록 0으로 계산합니까? –

+1

예, 오른쪽의 블록 0부터 시작합니다. 내 게시물을 수정했습니다. 죄송합니다. – dtgee

답변

2

먼저 차단합니다.

  • 넓은 "블록 크기"사람의 세트 : 사람 넓은 바로 이곳으로 이동 "블록 크기"의 (1<<size) - 1
  • 세트 : ((1<<size)-1) << (number*size)

먼저 우리가 할 자리에 비트를 취소합니다 우리가 원하는 비트를 고수하면 바뀝니다.

    클리어 마스크 비트
  • 이전 값 : newv << (number*size)
  • 새로운 값이 정확한 위치로 시프트 및 우측 폭 마스킹 : oldv & ~mask
  • 새로운 값이 정확한 위치로 시프트 (newv<<(number*size)) & mask
  • 이전 비트를 클리어하고 새로운 값은 삽입 : (oldv&~mask) | ((newv<<(number*size))&mask)

그래서 당신이 원하는 코드의 비트는 다음과 같습니다

,536,913,632 10
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 
+0

니스! 그러나 나는 '마스크'로 '&'ing의 요점을 보지 못했다. 마스크를 사용하여'&'하면 같은 결과를 얻습니다. 사용자가 블록 크기가 가질 수있는 최대 값보다 큰 새 값을 입력한다고 가정하고 계신 것 같습니까? 이 경우 어쨌든 이전 값을 변경하고 싶지 않습니다. – dtgee