Your Ad Here

2's Complement Negative Numbers

This is the system used in all computers that I know about at the present for representation of integers. If you have n binary digits, then positive numbers can be no larger than 2^(n-1)-1. (By 2^n, I mean 2 to the power n.) If x is a positive integer,then x is represented by its ordinary binary representation, and -x is represented by 2^n - x. It is also assumed that if you add two numbers and there is a carry out of the nth place, the carry is lost, and that is the case with all computers that I know about. If you add x and -x, in fact you are adding x and 2^n - x, and the result is 2^n, which is a carry out of the nth place, and is lost, so the result is zero, as it should be. If x is a positive number, then the first binary digit must be zero, because x<2^(n-1). Then 2^n-x will be greater or equal to 2^(n-1), so the first binary digit must be 1. Thus you can consider the first binary digit to be the sign, and it is 0 for positive numbers and 1 for negative numbers. Here are a few examples using n = 8 to illustrate these ideas:

1 is represented as 00000001. Then -1 is represented as 2^8-1 = 11111111. If you add these as binary numbers, you get 100000000, but this is 9 binary digits.

The left-most digit is simply lost, so the answer given by the adder is 00000000. 2 is represented by 00000010, and -2 is 11111110, and again their sum is 00000000.

10 (ten) is 00001010, and so -10 is 11110110, and again their sum is zero. Again assume signed char n; int k; If you write n = k;, the rightmost eight bits of k are copied into n. If you write k = n; and if n is positive (i. e. its leftmost bit is 0) then the 8 bits of n are copied into the rightmost bits of k and the rest of the bits of k are set to zero. If on the other hand, the first bit of n is 1, then n appears to be negative. Then n is copied into the rightmost 8 bits of k and the rest of k is set to 1's. That will make k have the same numeric value as n, considered as a 2's complement binary integer. You can declare unsigned char n;, then when n is copied to k, it is copied to the rightmost 8 bits of k and the rest of k is always filled with 0's. If you simply declare char n;, then some compilers assume that n is signed and some assume that n is unsigned. If it matters, you should declare signed or unsigned, whichever you want. If n represents an ascii character, then it is positive, because all of the ascii codes are 7 bits long, and the eighth bit, the leftmost one, is zero for all of them. Thus with ascii characters, it really doesn't matter whether n is declared signed or unsigned.

You can experiment. Here is a program that illustrates some of these ideas: (The x format assumes that the variable is an integer. When I tell it to print b using %x format, it converts b to an int first, and the result will have the 8 bits of b with 24 leading 1's in front of them. printf will omit leading zeros, but it will not omit leading non-zero bits, so it prints them all.)

 #include <stdio.h>
 void main()
 {
     signed char a = 10, b;
     unsigned char e;
     int c, d;

     b = -a;
     c = a;
     d = b;
     e = b;
     printf("a = %d (%02x)\n", a, a);
     printf("b = %d (%02x) e = %02x\n", b, b, e);
     printf("c = %d (%08x)\n", c, c);
     printf("d = %d (%08x)\n", d, d);
 }

Results:

 a = 10 (0a)
 b = -10 (fffffff6) e = f6 
 c = 10 (0000000a) 
 d = -10 (fffffff6)