1. ## Bitwise rotate array

Hi Guys,
First post!!
I come from micro controller land where we speak RISC asm,
so C has been a little difficult to grasp when it comes to dealing with bits.

Help! I am going crazy. Bit shifting a byte array

and got this function working:
Code:
```void shiftl(void *object, size_t size) {

unsigned char *byte;
for ( byte = object; size--; ++byte ) {

unsigned char bit = 0;
if ( size ) {
bit = byte & (1 << (CHAR_BIT - 1)) ? 1 : 0;
}

*byte <<= 1;
*byte  |= bit;
}
}
```
The trouble I'm having is reversing it to make a new function to rotate right instead of left.
I know that object is the beginning of the array and size is the size,
so to shift right I should begin from object+size to make the for
loop run backwards. I don't know what ++byte is for.

Also, does;
Code:
` if ( size ) {}`
mean if size does not equal zero? or greater than zero?
I've never seen that before.
I see where the byte is shifted, but don't understand:
Code:
`*byte  |= bit;`
any help appreciated, thanks  2. if (size) means 'if (size is nonzero)'. 'if' statements are true if the value is any nonzero value. they are false if the term is 0.

a left shift puts a 0 in the first bit. the *byte |= bit is meant to put the high bit that was rotated out back into the zero position. 3. Originally Posted by dmh2000 if (size) means 'if (size is nonzero)'. 'if' statements are true if the value is any nonzero value. they are false if the term is 0.

a left shift puts a 0 in the first bit. the *byte |= bit is meant to put the high bit that was rotated out back into the zero position.
Thanks What is "++byte" doing in the for loop? 4. One gold star please Code:
```void shiftr(void *object, size_t size) {

unsigned char *byte;
for ( byte = object; size--; ++byte ) {

unsigned char bit = 0;
if ( size ) {
bit = byte & (1 >> (CHAR_BIT + 1)) ? 1 : 0;
}

*byte >>= 1;
*byte  |= bit;
}
}
```

EDIT,,,, bah! it's still not correct!  5. Just for simplicity, I'll use a variable of 4 bits

Is this what you need to do?

(notation value[element])

Before
1001 1101 0010

after
0100 1110 1001

If so, the algorithm should be easy to figure out...
if last element was odd before being shifted, then n = (n>>1) + 1000
otherwise n = n>>1 6. Yes, but looking at the results further,
it doesn't look like the original function carries the bit that drops off the left,
and feeds it into the right of the array, so it's not exactly what I'm after.
If you rotate it enough, the array will end up all zeros.

EDIT,,

this is the big rotate I really wanted (shift left though), but I didn't do it.

Code:
```void shiftl(void *object, size_t size) {

unsigned char *byte;

byte = object;  // NEW
unsigned char leftbit = byte & (1 << (CHAR_BIT - 1)) ? 1 : 0;   // NEW
for ( byte = object; size--; ++byte ) {

unsigned char bit = 0;
if ( size ) {

bit = byte & (1 << (CHAR_BIT - 1)) ? 1 : 0;
}
else {
bit = leftbit;  // NEW
}  // NEW
*byte <<= 1;
*byte  |= bit;
}
}``` 7. I'm having a hard time trying to figure out what you want to do.

Can you post your most current "shiftr()" and I'll have a look at what could be going wrong. 8. Now you've created a problem if the size of the buffer is less than 2 bytes.
I'd remove the conditional out of the loop. The following should perform correct rotates, both intentionally processing the bytes in the same order, as you had it:
Code:
```void shiftl(void *object, size_t size) {
unsigned char *byte, *last;
unsigned char firstBit;
if (size != 0) {
byte = object;
last = byte + size-1;
firstBit = byte >> (CHAR_BIT-1);
while (byte < last) {
byte = (byte << 1) | (byte >> (CHAR_BIT-1));
++byte;
}
(*last) = (*last) << 1 | firstBit;
}
}

void shiftr(void *object, size_t size) {
unsigned char *byte, *end;
unsigned char bit, nextBit;
if (size != 0) {
byte = object;
end = byte + size;
bit = *(end-1) & 1;
while (byte < end) {
nextBit = byte & 1;
byte = (byte >> 1) | (bit << (CHAR_BIT-1));
++byte;
bit = nextBit;
}
}
}``` 9. I read the rules, and thought you weren't supposed to do handouts...
Thanks tho The last function posted is the most current because it feeds the bits dropped from
the left end of the array back into the right end so it's a big rotate rather than a big shift. 10. Now you've created a problem if the size of the buffer is less than 2 bytes
I feel like I'm walking into a trap, but what sort of array has one element?
Wouldn't that just be a variable? 11. Originally Posted by xArt I feel like I'm walking into a trap, but what sort of array has one element?
Wouldn't that just be a variable?
You're getting a pointer, not an array. This is a perfectly valid function call :

unsigned char foo = 0xAB;
shift(&foo, sizeof(foo));

Or a variable can end up being more than 2 bytes :

unsigned long long foo2 = 0x1234567812345678ULL;
shift(&foo2, sizeof(foo2));

Probably best to handle all cases.   Popular pages Recent additions 