2016-02-08 40 views
0

林尝试设置一个字节的位,在此基础上函数签名设置位

int setbits(int old_value, int position, int width, int set_value) 

什么我做错了,因为它使返回0。

#include "stdafx.h" 

int setbits(int old_value, int position, int width, int set_value); 

int  _tmain(int argc, _TCHAR* argv[]) 
{ 
//for example turn hex 0xA (10 base 2) into (8 base 2) 
    int old_value = 0xA; 
    int position = 2; 
    int width = 4; 
    int set_value = 0; 

    printf("setbits, old_value %x, position %i, width %i, set_value %x, output %x",old_value,7,width,set_value,0); 
    getchar(); 
} 

//position - is the least significant bit of the old_value you wish to change 
//old_value - is the value before you start changing it 
//width - is the width in bits of the value you want to change (old_value width). 
//set_value - is the value you want to use to modify the bits 
int setbits(int old_value, int position, int width, int set_value) 
{ 
    int mask = 0x1; 
    int return_val = 0x0; 

    if (0 < position <= width) 
    { 
     //initialize mask 
     int c=0; 
     for (c; c<width ; c++) 
     { 
     mask = mask << 1; 
     } 

     printf("ini mask %x \n",mask); 

     //shift into position the set_value (aka state) 
     mask = mask >> position; 

     printf("shifted mask %x \n",mask); 
     //if state is 1 
     if (set_value) 
     { 
      return_val = mask | old_value; 
     } 
     else 
     { 
      return_val = (~mask) & old_value; 
     } 
    } 
    else 
    { 
     printf("setbits(), position is out of range, position : %x, width : %x", position, width); 
    } 
    return return_val; 
} 
+6

的[您如何设置,清除可能的复制并在C/C++中切换一个位?](http://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit-in-cc) –

+0

也,如果(0 <位置<=宽度)错误。它应该是'if((0 <位置)&&(位置<=宽度))'。 –

回答

2

纠正你的代码

int setbits(int old_value, int position, int width, int set_value) 
{ 
    int mask = 0x1; 
    int return_val = 0x0; 

    if ((0 < position) && (position <= width)) 
    { 
     //initialize mask 
     mask = mask << width; 

     printf("ini mask 0x%02X \n",mask); 

     //shift into position the set_value (aka state) 
     mask = mask >> position; 

     printf("shifted mask 0x%02X \n",mask); 

     //if state is 1 
     if (set_value) 
     { 
      return_val = mask | old_value; 
     } 
     else 
     { 
      return_val = (~mask) & old_value; 
     } 

     printf("returned value: 0x%02X\n", return_val); 
    } 
    else 
    { 
     printf("setbits(), position is out of range, position : %x, width : %x", position, width); 
    } 
    return return_val; 
} 

你的榜样,你会得到输出:

ini mask 0x10 
shifted mask 0x04 
returned value: 0x0A 

这正是预期的。

value --> 0x0A --> 0b00001010 
mask --> 0x04 --> 0b00000100 

~mask --> 0xFB--> 0b11111011 

value & ~mask = 0x0A 
1

处理这个问题,你可能(也可能不:)要考虑的是用几个简单的宏,例如另一种方式,

/* --- 
* bitfield macros (byte_bits=, with lsb=bit#0 and 128=bit#7set) 
* --------------------------------------------------------------------- */ 
#define getbit(x,bit) (((x)>>(bit)) & 1) /* get bit-th bit of x */ 
#define setbit(x,bit) ( (x) |= (1<<(bit))) /* set bit-th bit of x */ 
#define clearbit(x,bit) ( (x) &= ~(1<<(bit))) /* clear bit-th bit of x */ 
#define putbit(x,bit,val) \ 
      if(((int)(val))==0) clearbit((x),(bit)); else setbit((x),(bit)) 
#define bitmask(nbits) ((1<<(nbits))-1) /* a mask of nbits 1's */ 
#define getbitfield(x,bit1,nbits) (((x)>>(bit1)) & (bitmask(nbits))) 
#define putbitfield(x,bit1,nbits,val) /* x:bit1...bit1+nbits-1 = val */ \ 
     if ((nbits)>0 && (bit1)>=0) { /* check input */ \ 
      (x) &=  (~((bitmask((nbits))) << (bit1))); /*set field=0's*/ \ 
      (x) |= (((val)&(bitmask((nbits)))) << (bit1)); /*set field=val*/ \ 
      } else      /* let user supply final ; */