Home > Mobile >  Trouble understanding bit shifting as follows
Trouble understanding bit shifting as follows

Time:11-29

So I have written the code below which takes an unsigned int , shifts its bits 6 positions to the left then replaces the empty final 6 bits with another int value. However, when I run the code say with value 15, the first step works and I get a value of 960 (so shifting left by 6 works). But the or step does not seem to work and I get -1 when I actually need to get 1111111111111111 or i.e. 65535 (note the operand value in this case is -1)? Any help would be greatly appreciated. I understand it is something to maybe do with my types but s->data was defined as an unsigned int whilst operand is defined as an int so I do not know why the output of s->data gives a negative value.

typedef struct state { int x, y, tx, ty; unsigned char tool; unsigned int start, data; bool end;} state;

void dataCommand(int operand, state *s) {
    // shifts bits of current data fields six positions to left
    printf("BEFORE SHIFTING %d\n", s->data);
    s->data = s->data << 6;
    printf("AFTER SHIFTING %d\n", s->data);
    printf("OPERAND IS %d\n", operand);
    // last 6 bits replaced with operand bits of the command
    s->data = (s->data | operand);
    printf("AFTER OR %d\n", s->data);

}

CodePudding user response:

When operand is -1 it is actually 0xffffffff (32 ones in binary). So when you are ORing you get back 32 ones which is still -1.

Maybe what you wanted to do was masking 6 bits off the operand :

s->data = (s->data << 6) | (operand & 0b111111);

CodePudding user response:

You must mask the operand to select which bits are combined into the result.

-1 is converted to unsigned int in the s->data | operand expression, to the value UINT_MAX that has all bits set, hence oring operand sets all bits in the result, giving it a value of UINT_MAX, but since you use %d to output the value, you get -1.

Modify the code this way:

typedef struct state {
    int x, y, tx, ty;
    unsigned char tool;
    unsigned int start, data;
    bool end;
} state;

void dataCommand(int operand, state *s) {
    // shifts bits of current data fields six positions to left
    printf("BEFORE SHIFTING %u\n", s->data);
    s->data = s->data << 6;
    printf("AFTER SHIFTING %u\n", s->data);
    printf("OPERAND IS %d (%#x)\n", operand, operand);
    // last 6 bits replaced with operand bits of the command
    s->data = s->data | (operand & 0x3F);
    printf("AFTER OR %u\n", s->data);
}
  • Related