# Sign Bits

I recall the math class where negative numbers were introduced. I was appalled. From Star Trek, I easily accepted the concept of antimatter, but the notion of negative values deeply offended me.

As I learned about computers, negative binary numbers blew me away. In a clutch of bits, which is essentially how values on a computer are stored, how can you have something negative? I mean, binary is just one and zero, right? Where is the negative?

The answer is the sign bit.

In a binary value, the left-most bit is the sign bit — for signed integer values. The unsigned integer type values treat the bit as part of the number. But for a signed value, the bit is 0 for a positive value or 1 for a negative value, as crudely illustrated in Figure 1.

In Figure 1, the first value shown is -1, binary `11111111` for a signed byte-sized (char) integer value. For the unsigned data type, the value shown is 255. The latter value makes more sense to me. Therefore, to best illustrate how this nonsense works, a program is in order.

### 2021_04_03-Lesson-a.c

```#include <stdio.h>

int main()
{
signed char a = 0;
int x;

for( x=0; x<256; x++ )
{
printf("%d\n",a);
a++;
}

return(0);
}```

This code loops through char values from 0 to 256. But because variable `a` is signed, once it huts the value where the sign bit is flipped from 0 to 1, negative values are output. Here is the interesting part of that output:

```123 124 125 126 127 -128 -127 -126 -125```

After 127 (binary `01111111`) the next value is -128 (binary `10000000`). Below, I’ve modified the code to include my binbin() function, which is showcased in my C books for outputting binary values:

### 2021_04_03-Lesson-b.c

```#include <stdio.h>

char *binbin(unsigned char n)
{
static char bin;
int x;

for(x=0;x<8;x++)
{
bin[x] = n & 0x80 ? '1' : '0';
n <<= 1;
}
bin[x] = '\0';
return(bin);
}

int main()
{
signed char a = 0;
int x;

for( x=0; x<256; x++ )
{
printf("%d\t%s\n",a,binbin(a));
a++;
}

return(0);
}```

The code runs the same, but with an additional column in the output. Again, here is the interesting part:

```123     01111011 124     01111100 125     01111101 126     01111110 127     01111111 -128    10000000 -127    10000001 -126    10000010 -125    10000011```

As soon as the 8th bit (for a char) flips, the values output are negative. Further, they flow upward as variable `a` increments. Eventually, the value returns to zero.

The sign bit is significant for signed integer variables. In fact, you can force-flip the bit so that values turn negative, as demonstrated in the following code:

### 2021_04_03-Lesson-c.c

```#include <stdio.h>

char *binbin(unsigned char n)
{
static char bin;
int x;

for(x=0;x<8;x++)
{
bin[x] = n & 0x80 ? '1' : '0';
n <<= 1;
}
bin[x] = '\0';
return(bin);
}

int main()
{
signed char a = 0;
int x;

for( x=0; x<256; x++ )
{
a |= 0x80;
printf("%d\t%s\n",a,binbin(a));
a++;
}

return(0);
}```

This code is identical to the preceding example, save for a new Line 24: `a |= 0x80`. This statement sets the first bit in the byte to 1, which makes all the output negative. Again, the same chunk of output from the sample run as shown earlier:

```-5     11111011 -4     11111100 -3     11111101 -2     11111110 -1     11111111 -128    10000000 -127    10000001 -126    10000010 -125    10000011```

With the sign bit set, the first part of the output shows negative values, from -128 on up to -1. Then the loop starts over again at -128.

By the way, `10000000` is interpreted as -128 and not “negative zero.” Unlike other programming languages, C lacks an equivalent for negative zero. I explore this notion in next week’s Lesson.