Signed Number Representation
Just give me a sign
Up until now, we've treated the left-most digit (what is known in these representations as the most-significant digit), as simply another number when calculating the decimal value of a binary representation. This is fine, assuming that the number is consider unsigned.
However, if the number is considered signed, the most significant digit (MSD) takes on extra meaning.
  1. If the MSD is a 0, we can evaluate the number just as we would any normal unsigned integer, as we had in the previous part.
  2. However, if the MSD is a 1, this indicates that the number is negative.
The following signed number representations only make sense in the perspective of how many bits long the data type is. For example, if we are dealing with bytes, 0b10000000 is negative because the leftmost (most significant bit) is a 1. However, if we are dealing with shorts (16-bits long), 0b10000000 is actually not a negative number, because there are 8 more bits to the left of the 1 shown that are 0.
Note: For the exercises following, we will be dealing with bytes, 8-bit numbers.
Signed number representations
How do we evaluate a signed number with a 1 as the left-most digit? It depends on what signed number representation the number is represented in. The following are several different ways of representing negative numbers:
  1. Sign and magnitude
  2. One's complement
  3. Two's complement
Most modern languages, including Java, use two's complement. You will also learn several other representations in CS 61C as well as how floating point numbers are represented in bits.
Sign and magnitude
Sign-and-magnitude representation designates the most significant bit as the sign bit. If the sign bit is 1, the number is negative. If the sign bit is 0, the number is positive. Thus, the additive inverse of a number has simply the opposite sign bit. Consider the following 4-bit numbers in binary:
0b0100 is 4 (sign-and-magnitude)
0b0100 is 4 (unsigned)
0b1100 is -4 (sign-and-magnitude)
0b1100 is 12 (unsigned)
Self-test: Sign and magnitude
What is the decimal value of these bytes (8-bit numbers) with sign-and-magnitude representation?
0b10010001
Toggle Solution
-17
0b10000010
Toggle Solution
-2
0b00001111
Toggle Solution
15
What is the sign-and-magnitude byte representation of these decimal numbers?
6
Toggle Solution
0b00000110
-11
Toggle Solution
0b10001011
-20
Toggle Solution
0b10010100
One's complement
In one's complement, the negative value of a number is the "opposite" of a positive number. In other words, the additive inverse of a number is calculated by simply flipping all of the number's bits:
0b0100 is 4 (one's complement)
0b0100 is 4 (unsigned)
0b1011 is -4 (one's complement)
0b1011 is 11 (unsigned)
Self-test: One's complement
What is the decimal value of these bytes under one's complement representation?
0b10010001
Toggle Solution
-110
0b10000010
Toggle Solution
-125
0b00001111
Toggle Solution
15
What is the one's complement byte representation of these decimal numbers?
6
Toggle Solution
0b00000110
-11
Toggle Solution
0b11110100
-20
Toggle Solution
0b11101011
Two's complement
To calculate the additive inverse of a number, flip all the bits and add 1. For example, let's evaluate the two's complement of 0b1001. There are two ways we can do this:
  1. Flip every bit, add 1, analyze what the representation would be in decimal, and tack on a negative sign.
  2. 0b1001 → 0b0110 → 0b0111 → 7 → -7
  3. Analyze the bits as representing unsigned numbers, but interpret the most-significant digit as negative rather than positive.
  4. 0b1001 = -1 * 2^3 + 0 * 2^2 + 0 * 2^1 + 1 * 2^0
           = -8 + 1 = -7
Both of these ways verify that 0b1001 in two's complement is equivalent to -7 in decimal. You can use whichever method you find the easiest for calculating decimal values.
Self-test: Two's complement
What is the decimal value of these bytes using two's complement representation?
0b10010001
Toggle Solution
-111
0b10000010
Toggle Solution
-126
0b00001111
Toggle Solution
15
What is the one's complement byte representation of these decimal numbers?
6
Toggle Solution
0b00000110
-11
Toggle Solution
0b11110101
-20
Toggle Solution
0b11101100
Activity: Nom representation of numbers
Nom is a class that defines a way of representing ints as base-36 bitstrings. This means that every bit in a Nom representation can be 0-9 or A-Z. As in hexadecimal representation, A refers to 10, and B refers to 11. Thus, Z refers to 35. Nom is a base-36 representation because each bit can be one of 36 different values.
Using what you've learned thus far, complete the toString and toBinaryString methods in ~cs61bl/code/lab28/Nom.java. The value instance variable in Nom can be a positive or negative int. The toString method returns the base-36 representation of the int value, and the toBinaryString method returns the base-2 representation of the int value.
Note that because the value instance variable is signed, the Nom class should deal with two's complement. Refer to the examples in the comments carefully.