Shifting the sign bit in .NET

Dinah picture Dinah · Sep 30, 2009 · Viewed 7.6k times · Source

I'm reading bits from a monochrome bitmap. I'm storing every 16 bits in a short in the reverse order. If the bit in the bitmap is black, store a 1. If white, store a 0.

E.g.: for bitmap: bbbw bbbw bbbw wwww
my short is: 0000 0111 0111 0111

The 1st way I tried to do this was:

short m;
// ...
Color c = bmp.GetPixel(j, i);
if (c.R == Color.Black)
    m |= short.MinValue;
m >>= 1;
// ...

After one assignment and shift, I got the expected -32768 (1000 0000 0000 0000).
After the 2nd time I got -16384 (1100 0000 0000 0000).

I changed my code to use ushort and changed the if line to s |= (ushort)Math.Pow(2, 15); and now it works.

My question is: why will the sign bit not shift in .NET? Is there a way to shift the sign bit?

Answer

Robert Cartaino picture Robert Cartaino · Sep 30, 2009

In C#, shifts are arithmetic shifts (in contrast to logical shifts). In a right arithmetic shift, the sign bit is shifted in on the left, so the sign of the number is preserved. A right shift is equivalent to dividing by 2:

alt text

If you want a logical shift (no sign extension), use unsigned numbers:

alt text