1

Does not work as expected becuase it does not set the MSB bit correct. I am using metrowerks compiler.

//shifting right 5 characters
char * buffer;
buffer=global_buffer;
for(i=0;i<5;i++) //shift right for 1;
{
    buffer[17-i]=(buffer[17-i]>>1)|(buffer[17-i-1]<<7);
}

EDIT input buffer (just before for loop) 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x2F,0xA0,0xC6,0x9D

i got after for loop 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x17,0xD0,0xE3,0xCE

Luka Rahne
  • 10,336
  • 3
  • 34
  • 56
  • 6
    Define "correct." What is your input? What output are you expecting? What output are you seeing? – jason Dec 14 '09 at 18:23
  • Your compiler implements "char" as "signed char". Use either of the answers below to keep the shifted value from keeping the sign bit intact. – Richard Pennington Dec 14 '09 at 18:33

2 Answers2

9

You probably want "unsigned char *buffer;" This will shift zeros into the top bits rather than retaining the sign bit.

Richard Pennington
  • 19,673
  • 4
  • 43
  • 72
  • Right shifting a signed value does not always retain the sign bit. See Steve Jessops Answer. Also see some of the discussion with the question: http://stackoverflow.com/questions/1857928/right-shifting-negative-numbers-in-c – Trent Dec 15 '09 at 00:34
  • 1
    @Trent: I didn't tell him to right shift a signed value. I told him to right shift an unsigned value. – Richard Pennington Dec 15 '09 at 01:46
  • @Trent: In fact, as your link says, even signed shifts usually work as expected. I'm not aware of an architecture (in current use) that they don't. – Richard Pennington Dec 15 '09 at 01:58
  • 1
    Trent gave an example in a comment to an answer on that question which makes the same incorrect claim: "The Microchip C18 compiler (a link to the user guide can be found here: http://tinyurl.com/ybt2svs - see section B.4)". I'm not aware of a CPU that has "signed" and "unsigned" registers, so note that it's down to the compiler what shift is used for signed integer types. The architecture has nothing to do with it. Unless it doesn't have an arithmetic shift at all, in which case it constrains what compilers can do efficiently on that architecture. – Steve Jessop Dec 15 '09 at 03:11
  • @Richard, I know you told him to shift a unsigned value, but you also incorrectly implied that right shifting a signed value retains the sign bit. – Trent Dec 15 '09 at 05:06
  • @Trent, His compiler does retain the sign bit. – Richard Pennington Dec 15 '09 at 11:18
2

"it does not set the MSB bit correct".

The C standard says:

6.5.7/5 ... If E1 has a signed type and a negative value, the resulting value is implementation-defined.

See this draft, for example: http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf

Presumably char is signed on your compiler, so you should check your compiler docs to see what is the correct value of the MSB. And all the other bits.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699