CDA3101 Recitation Section 4 Number Representations Pointers Unsigned Binary Numbers ● ● Unsigned integers can be stored in 32 bit registers as unsigned binary numbers. The place value of each binary digit is 2 n, where n counts [0...31]. 1000 0010 0001 0100 0000 1000 0100 0001 225 231 ● 220 218 To convert back to decimal: N n ∑ DIGIT n (2 ) n=0 211 26 20 Decimal → Unsigned Binary ● ● ● ● To convert from decimal to unsigned binary, repeatedly divide by 2, taking the remainder from each step as the next binary digit. This builds the number from right (lsb) to left (msb) Logically, it works because each division by 2 is a one bit shift right operation. The remainder following the operation is the bit that got shifted out. Stop when you've divided the number down to 0. ● Continuing past this point just keeps adding 0s to the left side of the number. Problem 1 – Decimal → Unsigned Binary ● Write 112 in unsigned binary. Verify by converting back to decimal. 112 56 28 14 7 3 1 ● / / / / / / / 2 2 2 2 2 2 2 Result 56 28 14 7 3 1 0 Remainder 0 LSB 0 0 0 1 1 1 MSB Solution: 1110000 Now we convert 1110000 back to decimal. 26 25 24 26+25+24 = 112 Hexadecimal ● ● ● Hexadecimal is a way of representing bit sequences in a short form. Numerically, hex corresponds to the base 16 representation of the unsigned binary number represented by a bit pattern. Logically, hex is just the grouping of the bits into sets of 4. Binary → Hexadecimal ● Process: simply group bits into sets of 4, starting at the LSB. Pad left side of bit sequence as needed to make sure it has a length that is a multiple of 4. ● ● Note: if bit sequence is 2s compliment #, pad left side with 1s. Otherwise 0s. Hex symbols are [0,A] 0000 → 0 0001 → 1 0010 → 2 0011 → 3 0100 → 4 0101 → 5 0110 → 6 0111 → 7 1000 → 8 1001 → 9 1010 → A 1011 → B 1100 → C 1101 → D 1110 → E 1111 → F Decimal → Hexadecimal ● ● ● ● ● Option 1: simply convert to binary, then rewrite in hex Option 2: repeatedly divide by 16, taking the remainder from each step as the next hex digit. This builds the number from right to left Logically, it works because each division by 16 is a four bit shift right operation. The remainder following the operation is the hex digit (set of 4 binary digits) that got shifted out. Stop when you've divided the number down to 0. ● Continuing past this point just keeps adding 0s to the left side of the number. Problem 2 – Decimal → Hex ● Write 112 in unsigned hex. Verify by converting back to decimal. 112 / 16 7 / 16 ● Remainder 0 7 Solution: 0x70 Recall that we previously obtained 1110000 as the binary representation of 11210. From our chart. ● ● Result 7 0 0111 0000 → 0x70 Let's convert 0x70 back to decimal to check. 161 160 7(161) + 0(160) = 112 Signed Binary Numbers Recall from Lecture: ● Signed Magnitude: the number is written just like it's magnitude in unsigned binary, but with a sign bit in the left-most position. ● ● 1s Complement: the entire bit sequence is inverted for negative numbers. Left-most bit still determines sign. ● ● Problems: two zeros (-0, +0) and difficult arithmetic Problems: still two zeros (-0, +0) 2s Complement: just like 1's complement, except we invert the bit sequence and add 1 for negative numbers. Left-most bit still determines sign. ● No problems: the “add 1” causes -0 to have the same representation as +0 2's Complement → Decimal ● Option 1: ● ● ● Notice that positive numbers in 2's complement look the same as their unsigned binary representation (just with a leading 0) Simplest approach is to negate negative numbers, then convert from unsigned binary → decimal. Option 2: ● A neat trick that goes directly from 2's complement to decimal is to multiply the sign bit's place value by -1. 1000 0010 0001 0100 0000 1000 0100 0001 -231 225 220 218 211 26 20 Problem 3 – Negative Number ● Write -112 in 32-bit signed magnitude, ones complement, and twos complement. Recall that +112 in unsigned binary is 1110000 -112 in 32-bit Signed Magnitude: 1000 0000 0000 0000 0000 0000 0111 0000 -112 in 32-bit 1s Complement 1111 1111 1111 1111 1111 1111 1000 1111 -112 in 32-bit 2s Complement 1111 1111 1111 1111 1111 1111 1001 0000 2's Complement Arithmetic ● Standard binary arithmetic works. No modifications needed! – In other words, if you add two 2's Complement numbers using standard binary arithmetic, the result will be the correct answer in 2's Complement. Problem 4 – 2's Complement Arith. ● Do 4 + -112 using 32-bit 2's Complement arithmetic. 1111 1111 1111 1111 1111 1111 1001 0000 + 0000 0000 0000 0000 0000 0000 0000 0100 1111 1111 1111 1111 1111 1111 1001 0100 ● Let's convert that back to decimal to check. 1111 1111 1111 1111 1111 1111 1001 0100 ­(0000 0000 0000 0000 0000 0110 1011 + 1) ­(0000 0000 0000 0000 0000 0110 1100) ­(22+23+25+26) = ­108 Problem 5 – 2's Complement Arith. ● Do 113 + -112 using 32-bit 2's Complement arithmetic. 1111 1111 1111 1111 1111 1111 111 1111 1111 1111 1111 1111 1111 1001 0000 + 0000 0000 0000 0000 0000 0000 0111 0001 1 0000 0000 0000 0000 0000 0000 0000 0001 ● ● Answer is clearly correct. (0000 … 0001 = 113+-112 = 1) Safe to ignore the carry out because we are adding a positive number to a negative number. Overflow impossible. 2's Complement Overflow ● ● ● A one in the carry-out bit is a normal part of 2's complement arithmetic. Overflow occurs when you: ● Add two positive numbers and get a negative. ● Add two negative numbers and get a positive. Overflow can not occur when the signs of the numbers are different. Pointers Dereferencing (*): corresponds to load word or store word Address of (&): puts an address in a register Pointers c is int, has value 100, in memory at address 0x10000000, p in $a0, x in $s0 /* p gets 0x10000000*/ # p = 0x10000000 p = &c; lui $a0,0x1000 ori $a0,0x0000 /* x gets 100 */ # dereferencing p x = *p; lw $s0, 0($a0) /* c gets 200 */ *p = 200; addi $t0,$0,200 sw $t0, 0($a0)