0

Im try to set the bits of a byte , based on this function signature

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

what am I doing wrong, because it keeps returning 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; 
}
Vikas Gupta
  • 4,455
  • 1
  • 20
  • 40
cyber101
  • 2,822
  • 14
  • 50
  • 93
  • 6
    Possible duplicate of [How do you set, clear and toggle a single bit in C/C++?](http://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit-in-c-c) – Box Box Box Box Feb 08 '16 at 07:13
  • Also, `if (0 < position <= width)` is wrong. it should be `if ((0 < position) && (position <= width))`. – Balaraman L Feb 08 '16 at 07:16

2 Answers2

2

Correcting your code

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;
}

With your example you'll get the output:

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

That it is exactly what expected.

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

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

value & ~mask = 0x0A
LPs
  • 16,045
  • 8
  • 30
  • 61
1

Another way of approaching this problem that you might (or might not:) want to consider is with a few simple macros, e.g.,

/* ---
 * bitfield macros (byte_bits=76543210, 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 ; */
John Forkosh
  • 502
  • 4
  • 14