Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shifting the sign bit in .NET

Tags:

c#

.net

bit-shift

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?

like image 816
Dinah Avatar asked Sep 30 '09 17:09

Dinah


People also ask

How do you flip a bit in C#?

If you want to flip bit #N, counting from 0 on the right towards 7 on the left (for a byte), you can use this expression: bit ^= (1 << N); This won't disturb any other bits, but if the value is only ever going to be 0 or 1 in decimal value (ie.

What is bit shifting operation?

Bit shifting is an operation done on all the bits of a binary value in which they are moved by a determined number of places to either the left or right.

What does bit shifting by 1 do?

Bitshifting shifts the binary representation of each pixel to the left or to the right by a pre-defined number of positions. Shifting a binary number by one bit is equivalent to multiplying (when shifting to the left) or dividing (when shifting to the right) the number by 2.

What does bit shifting by 0 do?

1 in binary is 0001 , then bitshifting it by 0 won't do anything, which aligns with what you observed. So any number x << 0 is equivalent to x * 2^0 , which is x * 1 , which is just x .


2 Answers

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

like image 82
Robert Cartaino Avatar answered Sep 29 '22 03:09

Robert Cartaino


http://msdn.microsoft.com/en-us/library/k2ay192e.aspx

"The >> operator shifts the bits of expression1 right by the number of bits specified in expression2. The sign bit of expression1 is used to fill the digits from the left. Digits shifted off to the right are discarded. The data type of expression1 determines the data type returned by this operator."

like image 29
LibraRocks Avatar answered Sep 29 '22 04:09

LibraRocks