views:

52

answers:

4

Guys,

I have a value thats 5 bits in length. 4 bits determine the number and the 5th bit determines the sign, there by holding any value between -16 and +15. How can I accomplish sign extending from a constant bit width in C#? I know in C, I can use something like the follow to accomplish this:

int x; // convert this from using 5 bits to a full int
int r; // resulting sign extended number goes here
struct {signed int x:5;} s;
r = s.x = x;

How can I do something similar to this in C#?

+1  A: 

It's not really clear what you mean, but it could be as simple as:

int fiveBits = normal & 0x1f;

and for the reverse:

int normal =  fiveBits < 16 ? fiveBits : fiveBits | -32;

If you could suggest some original input and desired output, that would help.

Jon Skeet
Hey Jon. Stated simply, I have a value, that is contained in an sbyte. This sbyte is 8 bits in length, by definition. I only care about the first 5 bits. The value I'm trying to extract from these 5 bits are actually a nibble (4 bits) in length, thus holding a value between 0-15. The 5 bite determines the sign (thus making my possible value range -16 thru +15). So, as an example, if my sbyte value is equal to 10 (01010 binary) then my result should be 10. If my sbyte value is equal to 26 (11010 binary) then my result should be -6 (because my 5th bit is 1 or signed). Does this make sense?
icemanind
@icemanind: So I've given you an example using `int` - you should be able to just cast the results to `sbyte` in each case.
Jon Skeet
A: 

This is a twos-complement system, yes? The "sign bit" in that case is just as important as the other 4 bits, because 10000 = -16 while 00000 = 0. So, you can't just worry about the four-bit nibble.

To answer the question, the smallest primitive integral type is a byte; there are some implementations using individual bits, but if you look at the MSIL you'll probably find the bits are packed into bytes. However, you can cast your 5-bit integer into an 8-bit byte variable by moving your fifth bit to the 8th bit:

byte nibble = GetMy5BitValue();

byte sign = nibble & 32 << 7 // results in 00000000 or 10000000

byte restOfNumber = nibble - ((nibble >> 4) << 4); //results in 0000xxxx

sbyte result = sign + restOfNumber; //the same value as nibble, represented in 8 bits

I'm sure there's a simpler way, but this should work and it pretty much self-documents if you know what bit-shifting does.

KeithS
A: 

Perform a left shift followed by an arithmetic right shift to move the sign bit into the high position and then back. The arithmetic right shift will perform the sign extension for you.

Of course this depends on having a working arithmetic shift operation. The abstract C language does not (it's implementation-defined whether it works or not), but most implementations do. I'm not sure about C# but I would guess it has one.

R..
A: 

I'm just writing a C function (because I don't really know C#) that will do this using operations that I know are available in C#.

int five_bit_to_signed(int five_bit) {
     int sh = sizeof(int)-5;
     int x = five_bit << sh; // puts your sign bit in the highest bit.
     return x >> sh;  // since x is signed this is an arithmatic signed shift
}
nategoose