Integer Arithmetic

Operations we'll get to know (and love):

The rules for doing the arithmetic operations vary depending on what representation is implied.


Prerequisite Material from 252 (Starts Here)

A Little Bit on Adding

For adding unsigned integers, use the following truth table as a guide.


	carry in  a  b | sum  carry out
	---------------+----------------
	   0      0  0 |  0    0
	   0      0  1 |  1    0
	   0      1  0 |  1    0
	   0      1  1 |  0    1
	   1      0  0 |  1    0
	   1      0  1 |  0    1
	   1      1  0 |  0    1
	   1      1  1 |  1    1
                       |
       a      0011
      +b     +0001
      --     -----
     sum      0100

It is really just like we do for decimal!

    0 + 0 = 0
    1 + 0 = 1
    1 + 1 = 2  which is 10 in binary, sum is 0 and carry the 1.
    1 + 1 + 1 = 3  sum is 1, and carry a 1.

Addition

Unsigned integers

It is just like the simple addition given above.

Examples:

      100001           00001010 (10)
     +011101          +00001110 (14)
     -------          ---------
      111110           00011000 (24)

Ignore (throw away) carry out of the msb.

We do unsigned addition with the assumption that we are working of a fixed precision value. Fixed precision means that the number of bits can not change.

Two's Complement integers

The rules:

Examples:



    00011 (3)         101000               111111 (-1)
  + 11100 (-4)      + 010000             + 001000 (8)
  ------------      --------             --------
    11111 (-1)        111000             1 000111 (7)
                                         ^
					 this bit is thrown away

Subtraction

general rules:

    1 - 1 = 0
    0 - 0 = 0
    1 - 0 = 1
   10 - 1 = 1
    0 - 1 = borrow!

Unsigned integers

It only makes sense to subtract a smaller number from a larger one.

Example:


     1011 (11)   must borrow
  -  0111 (7)
  ------------
     0100 (4)

Two's Complement integers

Change the problem to addition!

a - b becomes a + (-b)

So, get the additive inverse of b, and do addition.

Example:

    examples

   10110 (-10)
 - 00011 (3)    -->       00011
 ------------              
			  11100 (after taking the 1's complement)
			+     1
			-------
			  11101 (-3)
 so do

     10110 (-10)
   + 11101 (-3)
   ------------
     10011  (-13)
  (throw away carry out)

Overflow

In Addition

For unsigned integers, overflow occurs when there is a carry out of the msb.

	   1000 (8)
	  +1001 (9)
	  -----
	 1 0001 (1)

For 2's complement integers, overflow occurs when the signs of the addends are the same, and the sign of the result is different

	  0011 (3)
	+ 0110 (6)
	----------
	  1001 (-7)   (note that a correct answer would be 9, but
		       9 cannot be represented in 4-bit 2's complement)

A detail: you will never get overflow when adding 2 numbers of opposite signs.

In Subtraction

Prerequisite Material from 252 (Ends Here)


Unsigned Multiplication

     0 x 0 = 0
     0 x 1 = 0
     1 x 0 = 0
     1 x 1 = 1

Longhand, it looks just like decimal.

The result can require 2 times as many bits as operands.

Example:

        0111 (7)
      * 0110 (6)
 -----------
        0000
       0111
      0111
   + 0000
 -----------
      101010 (42)

If more bits are needed for the result, zero-extend this sum.

  101010 becomes 00101010

Unsigned Division

	        quotient
             ----------------
     divisor | dividend

Or, written as fractions:

     dividend
     --------
     divisor

Example:

      15 / 3         1111 / 011

	       0101
             -----------
        011  | 1111
	      -0 
	      -- 
	       11
             - 11
	     ----
	        01
	        -0 
	        -- 
                 11
               - 11
	       ----
                  0  (remainder)

Another example:

      20 / 3         010100 / 011
               000110 (quotient = 6)
             -----------
        011  | 010100
              -0
             ---
               01
               -0
              ---
               010
                -0
               ---
               0101
              - 011
               ----
	       00100
               - 011
                ----
	         0010
                -   0
                 ----
		   10 (remainder = 2)

Logical Operations


Prerequisite Material from 252 (Starts Here)

They are done bitwise. (Just like in C, Java, and C++.)

Bitwise means corresponding bits of the operands are operated on, with the single bit result going into the corresponding bit of the result.

Bit 0 of X goes with bit 0 of Y, and the result goes in bit 0.

For example:


                     X =  0011
		     Y =  1010

       X  AND  Y is       0010
       X   OR  Y is       1011
       X  NOR  Y is       0100
       X  XOR  Y is       1001
		etc.

Prerequisite Material from 252 (Ends Here)


Shift Operations

This is a way of moving bits around within a word. It exists in many high level languages (such as C), but is less commonly used, since there is little call for it in high level language source code.

A shift by n places is the same as n shifts by 1 place.

There are 3 types, and each type can go either left or right.

  1. logical
  2. arithmetic
  3. rotate

Usage Examples

All architectures provide instructions to do a variety of bitwise logical operations and shift operations. Which are included in the instruction set varies, but will form a sufficient set for doing any necessary operations.

For the examples that follow, pretend that an architecture has the following insturctions. This set corresponds to available instructions on the MIPS architecture, although simpifications have been made with respect to where the operands are.

All the variables are presumed to be integer sized.

	not   x, y         x <-  NOT (y)
	and   x, y, z      x <-  (y) AND (z)
	or    x, y, z      x <-  (y) OR (z)
	nor   x, y, z      x <-  (y) NOR (z)
	nand  x, y, z      x <-  (y) NAND (z)
	xor   x, y, z      x <-  (y) XOR (z)
	xnor  x, y, z      x <-  (y) XNOR (z)

	sll   x, y, value     x <- (y), logically left shifted by value bits
	srl   x, y, value     x <- (y), logically right shifted by value bits
	sra   x, y, value     x <- (y), arithmetically right shifted by
					value bits
	rol   x, y, value     x <- (y), rotated left by value bits
	ror   x, y, value     x <- (y), rotated right by value bits

A common student question occurs as a result of learning of the shift and logical operations: what are they used for?

Bunch of flags Example

A certain program has a bunch of boolean values that it will need to maintain.

Place all these (bit-sized) variables into one (word-sized) integer variable:

      Bit number:     31     30 . . . .  2    1    0
      Contents       var31  var30       var2 var1 var0

So, we have up to 32 variables placed into one integer. Let this integer be called var.

What would we want to do to these boolean variables? Answer: individually set (make a 1) or clear (make a 0) a variable.

code to set var5:

              or  var, var, 0x00000020

Whatever was in all bits other than bit 5 remain the same, and bit 5 (called var5 for this example, but not in code) gets the value 1.

code to clear var12 and var3:

              and  var, var, 0xffffeff7

Whatever was in all bits other than bits 12 and 3 remain the same, and bits 12 and 3 get the value 0.

The value 0xffffeff7 (or 0x00000020 in the previous example) is called a mask. It specifies the settings of bits. Here is the mapping of some of the bits to show how the mask was created.

      bit #      15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
      contents    1  1  1  0  1  1  1  1  1  1  1  1  0  1  1  1

String Manipulation Example

Suppose that we want to do operations on strings. (A string is a bunch of characters that happen to reside next to each other in memory.)

What operations might be appropriate? Insert characters? Concatenate strings? Switch order of characters? Change lower case to upper case?

What do strings look like?
The ASCII characters are placed into memory one following another. Yet, to operate on parts of strings, we might want to work on integer-sized chunks. . . An operand the size of an integer is most often called a word on a computer.

Part of a string in a 32-bit word:

           -------------------------
	   | 'A' | 'B' | 'C' | 'D' |
           -------------------------

Call this variable x. Here is a code fragment that reverses the middle two characters, without changing the rest.


           and   temp1, x, 0x00ff0000   # extract out the 'B' byte
           and   temp2, x, 0x0000ff00   # extract out the 'C' byte
	   and   x, x, 0xff0000ff       # clear middle 2 bytes
	   srl   temp1, temp1, 8        # move the 'B' 1 byte to right
	   sll   temp2, temp2, 8        # move the 'C' 1 byte to left
	   or    x, x, temp1            # merge moved 'B' back in
	   or    x, x, temp2            # merge moved 'C' back in

Copyright © Karen Miller, 2006