3

I'm programming an arduino for led matrix project with shift registers i have to rotate output value (which is a byte) but when i use "<<" operator it does not rotate the value properly ,simply it adds zero to LSB .

byte ilk=0b01100001;
int latch=10;
int clock=8;
int data=9;
void setup(){
pinMode(latch,OUTPUT);
pinMode(data,OUTPUT);
pinMode(clock,OUTPUT);
}

void loop(){
  digitalWrite(latch,LOW);
  shiftOut(data,clock,MSBFIRST,ilk);
  digitalWrite(latch,HIGH);
  ilk=ilk<<1;
  delay(200);
}

How can i do this right way ?Is there any operator like ROL.

1

3 Answers 3

5

Because << is not the "rotate left" operator. It's the arithmetic left shift operator. You can use something like

uint32_t rotl(uint32_t n, uint32_n b)
{
    return (n << b) | (n >> (32 - b));
}

instead. Write sizeof(n) * CHAR_BIT - b in the right-hand side of the bitwise OR operator if you want this to be independent of the size of the integral type you use.

Sign up to request clarification or add additional context in comments.

1 Comment

This has undefined behaviour when b == 0, because it involves a shift by >= the width of the type. See stackoverflow.com/questions/776508/… for the current best-practice compiler-friendly C that will produce good ASM.
1

You could also code this like

uint16_t tmp = ilk << 1;
ilk = (uint8_t)tmp + *(((uint8_t *)(&tmp))+1);

The idea is that &tmp is a pointer to tmp as a word. Then the cast converts it to a byte pointer. Adding 1 to this pointer moves it up one byte. Dereferencing it delivers the high byte of tmp which is added to tmp. Then assigning the result to ilk takes the low byte of this operation. I did not double check but if the compiler is smart enough it can optimize this to "add the hi byte of tmp to tmp and take only the low byte of the result".

Or you could implement it as

ilk = ilk << 1 + (ilk >= (1 << sizeof(ilk));

In your case

ilk = ilk << 1 + (ilk >= 128);

Notice that both of my solutions do not require the compiler to optimize a shift of several bits.

Comments

-1

Off the top of my head this should work, the overflow bits get discarded

byte temp = ilk & 1;
ilk <<= 1;
ilk |= (temp >> sizeof(temp));

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.