Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bitwise rotate right of 4-bit value

Tags:

I'm currently trying to control a stepper motor using simple full steps. This means that I'm currently outputting a sequence of values like this:

1000 0100 0010 0001 

I thought an easy way to do this was just take my 4-bit value and after each step, perform a rotate right operation. "Code" obviously isn't following any kind of syntax, it's simply there to illustrate my thoughts:

step = 1000; //Looping Motor_Out(step) //Rotate my step variable right by 1 bit Rotate_Right(step, 1) 

My problem is that there obviously isn't any 4-bit simple data types that I can use for this, and if I use an 8-bit unsigned int I will eventually rotate the 1 off to the MSB, which means the 4-bit value I'm actually interested in, will turn into 0000 for a few steps.

I've read that you can use structs and bit-fields to solve this, but the majority of things I read from this is telling me that it's a very bad idea.

like image 438
NT93 Avatar asked Oct 26 '16 11:10

NT93


People also ask

How do you rotate a bit right?

Right rotation of bits in C programming is supported using bitwise right shift operator >> . Similar to left shift, right shift operations also results in bit loss. On every shift operation the least significant bit is dropped.

What is bitwise rotate?

In computer programming, a bitwise rotation, also known as a circular shift, is a bitwise operation that shifts all bits of its operand. Unlike an arithmetic shift, a circular shift does not preserve a number's sign bit or distinguish a floating-point number's exponent from its significand.

What is the difference between bit shifting and bit rotating?

Bit rotation is similar to bit shift. It actually is bit shift but with a difference. The end bits, MSB or LSB are not any more lost and they come back on the other side of the string. Bit rotation is also known as circular bit shift.


2 Answers

With only 4 possible values you would use a table with 9 elements:

unsigned char table_right[] = { [0x1] = 0x8 , [0x2] = 0x1 , [0x4] = 0x2 , [0x8] = 0x4 }; 

When you need the next value you simply use the current value as the index:

unsigned char current = 0x4;    //value is: 0b0100 unsigned char next = table_right[current];  //returns: 0b0010 assert( next == 0x2 ); 

Doing this in a loop, will loop through all four possible values.

Conveniently, passing an invalid value, will return a zero, so you can write a get function that also asserts next != 0. You should also assert value < 9 before passing the value to the array.

like image 161
2501 Avatar answered Dec 21 '22 11:12

2501


Just use an int to hold the value. When you do the rotate copy the least significant bit to bit 4 and then shift it right by 1:

int rotate(int value) {     value |= ((value & 1) << 4); // eg 1001 becomes 11001     value >>= 1;                 // Now value is 1100     return value; } 
like image 42
Sean Avatar answered Dec 21 '22 11:12

Sean