More Negative Integers

The far left bit in a signed integer value — no matter how wide the integer — is the sign bit. If it’s set, the value is negative. Otherwise, the value is positive. But the sign bit is more than just a minus sign. It also plays into binary math.

Binary math. There’s a term to plunge a college sophomore into convulsions. It’s not that terrible of a concept. That’s because the early proto-nerds figured everything out for you. You just need to accept it.

For example, consider the elementary school math problem: 9 – 5

In your head (I hope), you know the result is 4. From your programming experience, you might even know that hexadecimal 0x09 minus 0x05 is equal to 0x04. That’s simple enough. Here are the values in binary:

9 = 0x09 = 0000-1001
5 = 0x05 = 0000-0101
4 = 0x04 = 0000-0100

In the computer, however, the problem isn’t really 9 – 5. No, it’s 9+(-5). At the low level, the processor adds bits. Even when the machine language instruction is SUBTRACT, the processor is adding bits.

In binary, -5 isn’t 1000-0101 it’s 1111-1011 or 0xFB. I’ll show how that translation works in this Lesson’s sample code later, but for now understand that 0xFB is the binary representation of -5. Math-wise, the problem is illustrated in Figure 1.

Figure 1. Binary addition of a positive and negative value.

Figure 1. Binary addition of a positive and negative value.

The values 0x09 (9) and 0xFB (-5) are added in Figure 1. Binary addition works the same as the math you already know:

0 + 0 = 0
0 + 1 = 1
1 + 1 = 0 and carry the 1 to the next digit

For the math in Figure 1, the sum at bit 3 gets carried all the way over past the sign bit (bit 7) in the value. This condition sets what’s called the carry bit in the processor. It might also be called an overflow and set an overflow flag. Regardless, the final value is 0x04 or 0000-0100, which is the result of subtracting 5 from 9 — or adding 9 and -5.

Don’t wrack your brain on this binary math! The processor handles all the details. A bigger question might be how do you get from 5 binary 0000-0101 to -5 binary 1111-1011. For that answer, you need to do some binary manipulation. The steps to convert a positive binary value to a negative binary value are:

1. Take the two’s complement of the original value, C operator: ~
2. Increment the result, C operator: ++

Here’s sample code that implements this process:

#include <stdio.h>

char *binbin(char n);

int main()
{
    int v;
    char i;

    printf("Enter a value (-127 to 127): ");
    scanf("%d",&v);
    i = (char)v;
    printf("Value = %d\n",i);
    printf("Binary: %s\n",binbin(i));
    i = ~i;
    printf("Two's complement = %d\n",i);
    printf("Binary: %s\n",binbin(i));
    i++;
    printf("Increment result = %d\n",i);
    printf("Binary: %s\n",binbin(i));

    return(0);
}

char *binbin(char n)
{
    static char bin[9];
    int x;

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

The code prompts for an input value between -127 and 127 (Line 10). Though the range of an signed char value really goes to -128, that specific value creates problems with the integer conversion required at Line 12. (Otherwise, int variable v pads bits on the left.)

At Lines 13 and 14, the original is shown in decimal and then binary, thanks to the binbin() function.

Line 15 converts variable i into its two’s complement value. Then Lines 16 and 17 display the result in decimal and binary.

Line 18 increments variable i, resulting in the final, negative value displayed in Lines 19 and 20.

Run the code a few times to test its output. Here is a sample run:

Enter a value (-127 to 127): 5
Value = 5
Binary: 00000101
Two's complement = -6
Binary: 11111010
Increment result = -5
Binary: 11111011

Also, note that when you start with a negative number, you get a positive value in return:

Enter a value (-127 to 127): -100
Value = -100
Binary: 10011100
Two's complement = 99
Binary: 01100011
Increment result = 100
Binary: 01100100

That’s pretty solid. Further, here’s the result when you process the value zero:

Enter a value (-127 to 127): 0
Value = 0
Binary: 00000000
Two's complement = -1
Binary: 11111111
Increment result = 0
Binary: 00000000

And all the mathematicians shout, “Amen!”

Leave a Reply