Question: How would I retrieve negative value from unsigned char. 

Say I have unsigned char which I passed into fun and just want to get 1st 6bits. Now these 6bits can have positive or negative value populated from some other function. I want to extract same value .
I can successfully extract positive value using 0x3F. But how about if it has negative value example

```
signed char my_6bitfunc(  unsigned char *val )
{
   unsigned char temp = *val & 0x3F;
   return temp;
}

// somewhere in main
 int main()
{
    signed char valneg = -31 ;
    signed char valpos = 31 ;

   signed char a = my_6bitfunc( &valneg );
    signed char b = my_6bitfunc( &valpos );

    printf("  val neg %d\n", a );  // not -31 but 33 ?
    printf(" val positive %d\n", b );
}

```

**o/p**  

expected value for a = -31 actual value = 33 why ? Wrong  

expected value for b = 31 actual value = 31 Correct.

Answer: 
To sign extend a twos complement field, use `((x ^ N) - N)` -- where `N` is the numeric representation of the sign bit, e.g., 32768 for 16 bits.

```
signed char my_6bitfunc (unsigned char *val)
{
   unsigned char temp = *val & 0x3FU;
   return ((signed char )(temp ^ 0x20U)) - 0x20;
}

```
Well, you can't just mask away the 2 upper bits for negative numbers. 

Why not?

Well, in 2's complement and 8 bit char variable (which is most common), you have:

```
-31 -> 11100001

```

If you mask by 0x3f you'll get

```
00100001

```

which is exactly 33 for an 8 bit 2's complement signed number. Consequently, your program prints 33.

In general you can't play around with the basic representation of numbers in the computer. On most systems there is no way to represent a signed number in 6 bits and print it using an 8 bit format. It is just not possible.

However, you can write a function that limits the range of an 8 bit signed number to 6 bit signed number. The C standard gives you a clue to how that could be done when converting between types with different numbers of bits. You could implement a similar conversion.

A 6 bit signed 2's complement number can hold -32 to 31. So if the input to your conversion function -75 you shall keep adding 31+1 (i.e. MAX+1) to the input until it is within the valid range.

```
-75 + (31+1) = -43 
-43 + (31+1) = -11 (which is in range)

```

But at the binary level you will need to save it as `11110101` as your computer most likely uses 8 bit as its smallest integer type.

If you know that the range of **negative** input is between -32 and -1 (and don't care for conversions when input is less than -32), you can leave the binary pattern unchanged for negative numbers. Like:

```
#include <stdio.h>

signed char my_6bitfunc(  signed char *val )
{
    if (*val < 0) return *val;  // Add this line
    return *val & 0x3F;;
}

 int main()
{
    signed char valneg = -31 ;
    signed char valpos = 31 ;

    signed char a = my_6bitfunc( &valneg );
    signed char b = my_6bitfunc( &valpos );

    printf("  val neg %d\n", a );  // not -31 but 33 ?
    printf(" val positive %d\n", b );
}

```

Output:

```
  val neg -31
 val positive 31

```