AMTH247 Lecture 5 Computer Arithmetic – Integer Arithmetic March 7, 2006 Contents 1 Binary, Decimal and Hexadecimal Representations 1.1 Binary to Decimal Conversion . . . . . . . . . . . . . . . . . . . . 1.2 Decimal to Binary Conversion . . . . . . . . . . . . . . . . . . . . 1.3 Hexadecimal Representation . . . . . . . . . . . . . . . . . . . . . 2 2 2 3 2 Integer Arithmetic 2.1 Unsigned Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Signed Integer Arithmetic . . . . . . . . . . . . . . . . . . . . . . 2.3 Overflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 4 5 6 1 1 Binary, Decimal and Hexadecimal Representations We are used to working with numbers in decimal or base 10 representation. However computers work with numbers in binary or base 2 representation and if we want to know how a particular number is represented in a computer, or conversely, what number corresponds to a given bit pattern then we need to know how to convert between binary and decimal representations. 1.1 Binary to Decimal Conversion This is easy – we simply expand the binary number in powers of two. For example, to convert (1000111.01001)2 to decimal: (1000111.01001)2 =1 × 26 + 0 × 25 + 0 × 24 + 0 × 23 + 1 × 22 + 1 × 21 + 1 × 20 + 0 × 2−1 + 1 × 2−2 + 0 × 2−3 + 0 × 2−4 + 1 × 2−5 =64 + 4 + 2 + 1 + 0.25 + 0.03125 =71.28125 Another representation of the fractional part is 9 (01001)2 = 5 2 32 1.2 Decimal to Binary Conversion We will find the binary representation of (123.456)10 The most convenient method treats the integer and fractional parts separately. To convert the integer part (123)10 to binary we calculate the quotient and remainder successive on division by 2. We can set out the calculation as follows: Quotient Remainder 123 61 1 30 1 15 0 7 1 3 1 1 1 0 1 The first remainder corresponds to the lowest (rightmost) bit, so (123)10 = (1111011)2 2 To convert the fractional part (.456)10 we successively multiply fractional parts by 2 and record the carries. We can set out the calculation as follows: Carry 0 1 1 1 0 1 0 0 .. . Fraction .456 .912 .824 .648 .296 .592 .184 .368 .736 .. . (Note that most decimal fractions have non-terminating binary representations.) The first carry is the most significant (leftmost) bit, so (0.456)10 = (0.01110100 . . .)2 and (123.456)10 = (1111011.01110100 . . .)2 1.3 Hexadecimal Representation When working with computer arithmetic it is common to use the hexadecimal or base 16 representation since it is more compact than than the binary representation. It is easy to convert between binary and hexadecimal by taking the binary digits in groups of four (since 16 = 24 ). The letters a to f are used for the hexadecimal digits from 10 to 15. binary hexadecimal decimal 0000 0 0 0001 1 1 0010 2 2 0011 3 3 0100 4 4 0101 5 5 0110 6 6 0111 7 7 binary hexadecimal decimal 1000 8 8 1001 9 9 1010 a 10 1011 b 11 1100 c 12 1101 d 13 1110 e 14 1111 f 15 Thus (123.456)10 = (1111011.01110100 . . .)2 = (7b.74 . . .)16 Converting between decimal and hexadecimal uses the same algorithms as binary/decimal conversion. For example (7b.74)16 =17 × 16 + 11 + 7 × 16−1 + 4 × 16−2 =123.453125 3 To convert the integer part of a number from decimal to hexadecimal, we divide successively by 16. The hexadecimal representation of (123)10 is found by: Quotient Remainder 123 7 11 0 7 so (123)10 = (7b)16 To convert the fractional part of a number from decimal to hexadecimal, we multiply successively by 16. The hexadecimal representation of (0.456) 1 0 is found by: Carry Fraction .456 7 .296 4 .736 11 .776 .. .. . . so (0.456)10 = (0.74b . . .)16 and (123.456)10 = (7b.74b . . .)16 2 2.1 Integer Arithmetic Unsigned Arithmetic Integers are typically stored in a 32 bit word. In unsigned integer arithmetic we think of the 32 bits as containing the binary representation of an integer the range 0 to 232 − 1, (i.e. 232 different numbers). Thus, for example the number 71 is represented by the word 00000000000000000000000001000111 Adding two 32 bit integers can result in integer which needs 33 bits for its representation. For example, adding 11000000000000000000000000000101 and 10000000000000000000000000000001 results in 1 01000000000000000000000000000110 4 This is called overflow and is even easier to produce for multiplication. Understanding overflow is important and we will return to it later. For the moment we will look at what happens when overflow is ignored. Ignoring overflow is equivalent to performing arithmetic modulo 232 . To see this, imagine performing binary arithmetic with an unlimited number of bits and then keeping only the lowest 32 bits of the result. This is the same as taking the remainder of the result on division by 232 , that is performing arithmetic modulo 232 . You should be familiar with arithmetic modulo a small integer like 8. In this case we have 8 representatives, say {0, 1, 2, 3, 4, 5, 6, 7}. The operations of addition, subtraction and multiplication are performed in ordinary integer arithmetic and then remainder on division by 8 is returned. Thus, for example 6 × 7 → 2 modulo 8. In modular arithmetic, two numbers are considered equal if the differ by a multiple of the modulus. This holds for negative numbers as well so, for example, 6 = −2 modulo 8. Negative numbers can also be used as representatives in modular arithmetic. For example, it doesn’t matter with we work with 6 or −2 when performing arithmetic modulo 8. We can equally well use the representatives {0, 1, 2, 3, −4, −3, −2, −1} instead of {0, 1, 2, 3, 4, 5, 6, 7} when working in arithmetic modulo 8. 2.2 Signed Integer Arithmetic Returning to 32 bit arithmetic, we can now see a clever way of representing negative numbers – we identify them with the corresponding positive number modulo 232 . This is called the 2’s complement representation. In this scheme the 32 bits are used to represent the nonnegative integers in the range 0 to 231 − 1 and the negative integers in the range −231 to −1. A nonnegative integer i is represented by its binary representation, but a negative integer −j is represented by the binary representation of the positive integer 232 − j to which its equivalent modulo 232 . For example, the integer -71 is represented by 11111111111111111111111110111001 and -1 by 11111111111111111111111111111111 To obtain the representation of a negative integer −j from the representation of j reverse all the bits of j and add 1 to the result. The sign of a 2’s complement integer is determined by its leading (leftmost) bit: non-negative numbers always have leading bit 0, negative numbers always have leading bit 1. Arithmetic with 2’s complement numbers is exactly the same as unsigned integer arithmetic. This results in two advantages when compared to representing negative numbers using sign and magnitude: 1. No special hardware is needed for integer subtraction, just take the 2’s complement and add. 5 2. The same operation is used for both positive and negative numbers. For example, in sign and magnitude arithmetic the actual operation performed in evaluating a + b may be addition or subtraction, depending on the signs of a and b. 2.3 Overflow Let us first consider unsigned arithmetic. We consider overflow to have concerned when the result of an arithmetic when the result of an arithmetic operation is a number outside of the range 0 to 232 − 1. This can occur with addition or multiplication and with subtraction when the result is a negative number. In fact overflow occurs exactly when we need to go beyond 32 bits in computing the result. When this occurs in hardware an overflow flag is set. What is done with this flag depends on the programming language and compiler. Most commonly it is ignored! Overflow is a little more subtle in signed integer arithmetic. Consider adding 71, 00000000000000000000000001000111 and −71 11111111111111111111111110111001 The result is computed using unsigned arithmetic 1 00000000000000000000000000000000 Overflow has occurred in hardware, although the result, 0, is obviously correct and we would not have considered an arithmetic overflow to have occurred. The opposite effect can also occur. Consider adding 230 01000000000000000000000000000000 to itself 01000000000000000000000000000000 The result is 0 10000000000000000000000000000000 No overflow has occurred in hardware, although the result, −231 , is not what we wanted and in this situation we would consider arithmetic overflow to have occurred. Thus we see that although signed and unsigned arithmetic are basically identical, they require different methods for the detection of overflow. Assignment Question1 Consider the addition a + b = c in 32 bit 2’s complement arithmetic. Show how arithmetic overflow can be detected by a rule relating the sign bits (i.e. the leftmost bits) of a and b to the sign bit of c. 1 This will appear as a question in Assignment 2. 6