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