Day 7

I. Last Time:
A. Binary Numbers
     1. Back to the basics: 1s and 0s
      Computers use a 2 digit counting system. Corresponds to
on/off of the "switches" used 
       Really it works just like the counting system you're used to,
just fewer digits:
         Counting Sequence: 0, 1, 10, 11, 100, 101, etc.
      2. Since we use at least 3 numbering systems in here,
I'll try to use one of the following notations:
         binary: b or base2
         decimal: d or nothing
         hexadecimal: h, or 0x 
      3. These digits can be used to represent numbers by realizing that,
like decimal, each place has a value dependent on the base. I.e. :
         9,824 = 9*1,000+8*100+2*10+4*1 = 9*10^3+8*10^2+2*10^1+4*10^0.
         Binary works essentially the same, but our digits only count to 2 
         (0-1 instead of 0-9), and we use powers of 2 rather than powers of 10.
         EX: 10 1101b= 1*2^5+0*2^4+1*2^3+1*2^2+0*2^1+1*2^0 = 46d
      4. Conversion from bin to decimal - see above
      5. Conversion from decimal to bin - repeated division by 2 w/ remaindes
         EX: 13/2=6 r 1
              6/2=3 r 0
              3/2=1 r 1
              1/2=0 r 1
        Divide until 0, read remainders from bottom to top.
        (Actually, this is the same as dividing by 2^3, 2^2, 2^1, 2^0, etc.)


II. New Stuff:
    A. Hexadecimal to store/represent binary - Note 1-to-1 correspondence
       Hexadecimal is base 16. (Digits of 0-15)
       Note that in binary, 4 digits can count up to 15.
       This is really why hexadecimal is used - 4 bin digits = 1 hex digit.
       4 binary digits is called a nibble.
       1 nibble = 4 bits
       1 byte = 2 nibbles = 8 bits

       The most fundamental unit of storage in most computers is 1 byte = 
       8 bits = 2 hexadecimal digits, so hex works really well.

       So, hex has 16 digits. They represent 0-15. 
       Decimal     Binary      Hexadecimal
         0          0000            0
         1          0001            1
         2          0010            2
         .          ....            .
     
       It's probably best to memorize this table so you can easily convert.

       Convert 0xAC to binary Ah=1010b, Ch=1100b => 1010 1100b
               0x4E to binary 4h=0100b, Eh=1110b => 0100 1110b
   
       Convert 110100 to Hex: 0011 0100b = 0011 0100b = 0x34

       Easy conversion to decimal (Same process as binary and decimal):
          0x7AC = 7*16^2 + A(10)*16^1 + C(12)*16^0 = 1964

    B. Sign Representations
       How do we do negatives in a computer? 
       We have to somehow store the sign within the number. 
       
       1. Sign Bit  (Sign Magnitude) - Assign a bit to represent the sign.
          Usually MSB is used.

         Pitfalls: This makes subtraction/negatives is difficult
                   There are 2 "zeros" at MSB=1 and MSB=0
                   The wraparound has 2 boundaries

         Pros: Numbers are "easy" to read

          3 bit example: 000 001 010 011, 100 101 110 111
                          0   1   2   3   -0  -1  -2  -3

          Uses: There are a few uses of sign magnitude representation...
                IEEE-754 Floating Point uses something similiar

       2. Binary Offset
          Subtract half of the largest Value from the largest value and 
          call the result 0. Everything else is numbered outward.

          3 bit example: 000 001 010 011 100 101 110 111
                         -4  -3  -2  -1   0   1   2   3
          
          Pitfalls: Again, Subtraction/negatives is difficult
          Uses: IEEE-754 uses binary offset to store the exponent on a number

       3. 1's Compliment
          In one's compliment a positive number is written in the same
          manner as an unsigned number. To find a negative, find the 
          representation of the magnitude and then flip (invert) each bit.

          Pitfalls: Subtraction is a little more difficult than 2's comp.

          Uses: JPEG uses 1's compliment to store numbers.
                (It's trying to compress data - minimize the number of
                 bits used. 1's compliment numbers can be stored in exactly
                 the number of bits needed for the magnitude of the number:
                 ex: 72: 100 1000b, -72= 011 0111. 7 bits either way.
                 Positive numbers begin with 1, negatives with 0)

       4. 2's Compliment
          Positive: Sames as unsigned
          Negative: Invert each bit and add 1

          3 bit example: 000 001 010 011 100 101 110 111
                          0   1   2   3  -4  -3  -2  -1

          A nice "ring" with only 1 abrupt boundary.

         Most Commonly Used represenatation for negative integers in computers.
 
        Pros: Makes 
        Uses: Practically all integer math...where negatives are allowed

        Shortcut: Locate RIGHTMOST ONE bit and invert everything to it's 
                  LEFT. (DO NOT invert that bit itself)

    C. Integer Math
       The reason we use 2's compliment is so we have the same "adding"
       technique regardless of whether we are adding positive or negative
       numbers.

       1. Addition - Just like decimal addition, we may add up to 3 digits!
          Basis: 0+0=0, 1+0=1, 1+1=10 (A carry), 1+0+0=1, 1+1+0=10, 1+1+1=11.
          
          Some examples with 4-bit binary:
          Carries       1
          A           0010 (2)          
          B           0011 (3)      Signed
          S           0101 (5)

          Carries       1
          A           0010 (2)          
          B           1110 (-2)    Signed
          S         1 0000 ("0")

          Carries       
          A           0111 (7)          
          B           1001 (9)    Unsigned
          S         1 0000 (16)

       2. Subtraction
          Just 2's compliment the number you want to subtract and then ADD.

    D. Conversion to/from 2's compliment - Negation
       Find magnitude
       1. Invert and add 1
        or
       2. Find rightmost one and invert to it's left.
          (Don't invert it!)

    E. Overall Problems
       1. Limited Storage -> Carry Problems (We'll discuss these much later)
          (Limited number line - NOT infinite!)
       2. When working by hand pay careful attention to the types of
          numbers being used so you know how to interpret the result.

    F. Math: Addition and subtraction in Binary
       1. Just like in decimal, when we add 2 big numbers, 
          we never realy add more than 3 digits at a time. 
          Simple 3-digit addition rules: 0+0+0...
       Subtraction: Just negative addition: 3-4=3+-4
          We just take the 2's compliment to find the negative and add.
      The reason 2's compliment is perfred is because addition and subtraction 
      and working with negatives all follow the same rules as addition. 

    G. Sign Extension/Padding: 
       In computers, numbers are almost always represented in a 
       certain number of bytes: 1,2,4, etc. Often we must convert from one
       size to another without actually changing the meaning of a number. 
       Convert 4-bit 2's compliment to 8-bit 2's compliment:
       0xA, 0x4. 
       What if these had been unsigned to unsigned?
       Unsigned to 2's compliment?                 

   H. ASCII - American Standard Code for Information Interchange
       1. A format for storing characters/symbols/language
         Basically a set of symbols is assigned to each unique 8-bit 
         (byte) number.
         Basicaly you can think of ASCII as a simple substuition code...
         Where you merly substitute every 8-bit number with the 
         appropriate symbol.
         Ex: What is: 0x48656c6c 0x6f20576f 0x726c6400 = "Hello World\0"
         Convert each BYTE = 0x48 = 72d = 'H', 0x65 = 101d = 'e' ...

         The string is terminated by a NULL (a 0) - Often used as a 
         special character to represent the "end" of the string.

         Other Special Characters: 
            Carriage Return: 0x0d, Line Feed: 0x0A, Form Feed, Bell, etc. 
       2. Neat ASCII Tricks/Features
          a. Cases differ by 32d = 0x20h
              I.e. by "ignoring" a bit, we can ignore case.
(Or adding 32 to make uppers into lowers,
subtract 32 to make lowers into uppers)
          b. Numbers and letters are sequential with no gaps
             '5'-'0' = 53d-48d = 5d. 
             This is a commonly used "conversion" trick
(Esp. in functions like "atoi")
       3. Numbers in ASCII are difficult to work with
          1. Math is difficult 
          2. Storage requires more space
             A 32-bit number stores 0-9999 in ASCII 
             and 0-4 BILLION in the integer format
       4. Alternatives: EBCIDIC, Unicode, etc.

   I. Endian-ness
       We think of computer memory as an array of bytes!!!
       (I can't emphasize this enough!)
       1. How does a computer memory work:
          a. Can retrieve whole words - working with numbers
          b. Can also retrieve individual bytes - working with ASCII
          If we store a word and retrieve a byte, which end is which
       2. BIG-Endian: The "BIG" end of the word comes first in memory
          Many Workstations
       3. LITTLE-Endian: The "Little" end of the word comes first in memory
          Intel Based Machines
       4. SPIM - Conforms to the endianess of the underlying machine
       5. What this REALLY means to US - Sometimes Memory Dumps look BACKWARDS
          (As in one of the homework problems)

   J. IEEE-754 Floating Point Numbers
       1. Why FP? 
          a. Represent "Big" and "Small" Numbers
          b. Problems: Limited numbers of "significant" digits
       2. How's it work:
     32-bit representation, range from +/- 2^127->2^(-127)
     (Very LARGE to Very Small numbers of both signs)
     (But NOT EVERY Number - some numbers just can't be represented...
      In reality computers aren't all that good at math!)

     1. How do we represent fractional values in Binary?
        Just like in decimal (essentially)
        1.5 = 1 1/2 = 1*2^0+1*2^(-1) = 1.1
        Conversion: Convert Integer Part, then Convert fractional Part
        Ex: 4.125 = 100.001
           .125*2 = 0.25 
           .25*2  = 0.5
           .5*2   = 1.0
       Much like the division technique, we can use a repreated 
       multiplication technique to determine the binary decimal.
       (Repeatedly multiply by two until there is no decimal remaining, 
        If use the "1's" digit going down as the exponent)
       Ex. 0.6875
       2*.6875 = 1.375
       2*.375  = 0.750
       2*.750  = 1.50
       2*.50   = 1.0
       0.6875d=0.1011b = 2^-1+2^-3+2^-4
       This is one of the vital steps in finding IEEE 754 format.
    2. IEEE-754 Components
       Bits     31      30-23      22-0 (position of the bit from right)
       # bits    1        8         23 (based on "power of two" idea)
       Mean      a        b          c
       a. Sign Bit: Is the number positive or negative: 1 bit 1=neg
       b. Exponent: An exponent to determine the magnitude of the numebr: 8-bits
       c. Significand: The "digits" of the number: 23 bits
    3. Conversion to IEEE-754
       Uses Scientific Notation 11.01 = 1.101 *2^1
       By this "normalizatin" process, we ALWAYS end up with a 1 before the decimal
       (except for 0 - special case) and we therefore always assume a 1, but don't 
       bother to actually store it.
       1. Sign bit - Sign of the number, 0=pos, 1=neg
       2. Significand: 
             Convert value into binary and scientific notation
             Store all but the leading one from the previous part
       3. Exponent - use the exp from the preceeding part
          Stored Exp = Real Exp + 127
          Note that this is offset binary, but with a little different 
             "center" than the form we discussed earlier.
       4. Convert bits to hex.

       Ex: Convert -24.625 to IEEE-754
       1. s = 1
       2. 24 = 1 1000
          .625 = .101
          24.625=11000.101
         Convert to sci not: 1.1000101*2^4
         Significand=1000101
       3. Stored Exp = 127+4 = 131 = 1000 0011 
          1 1000 0011 1000 1010 0000 0000 0000 0000...
          1100 0001 1100 0101 0000 0000 0000 0000 0...
          0xC1C50000
         
    4. Conversion FROM IEEE-754:
       Real Exp = Stored Exp-127
       Value = -1^(sign bit)*(1+significand)*2^Real Exp
      Ex: Convert 0xBF400000 to Decimal from IEEE-754
         1 0111 1110 100 0000...
      Sign = 1 = neg
      Stored Exp = 0111 1110b = 126
      Real Exp = 126-127=-1
      Significand = 1.1b = 1.5
      1.5^2^-1 = 0.75. 
      Final Result=-0.75
    NOTE: This is an approximation - many numbers can NOT be 
          exactly represented - they are "rounded" or "truncated"
          (This is one of the sources of greif in 228 - numerical methods)
          (A lot like 1/3 in decimal, many numbers don't "terminate")
       Ex: What is 0.1 in binary?
           0.1*2 = 0.2
              *2 = 0.4
              *2 = 0.8
              *2 = 1.6
              *2 = 1.2
              *2 = 0.4 (Look - we're repeating)

   K. MIPS and Data Types:
       MIPS uses a 32-bit word (MIPS is built to work with 32 bits of 
       data at a time)
       Question: What is the meaning of 0x476F6F64
       Answer: What type of data is it?
       1. ASCII: "Good" 
       2. Unsigned 32-bit Big Endian:
             = 4+6*16+15*16^2+6*16^3+15+16^4+6*16^5*7*16^6+4*16^7
             = 738,872,887,701,363
       3. 32-bit Signed 2's Compliment Big Endian:
          It's positive - Same as above
       4. Unsigned 32-bit Little Endian:
          REAL order: 0x646F6F47
             = 7+4*16+15*16^2+6*16^3+15+16^4+6*16^5*4*16^6+6*16^7
             = 422,214,075,772,758
       5. 32-bit Signed 2's Compliment Little Endian:
          It's positive - Same as above  
       6. As IEEE-754 Floating Point (Big Endian):
          0100 0111 0110 1111 0110 1111 0110 0100
          Sign = 0 = Positive
          Stored Exponent = 1000 1110 = 8*16+14 = 142.
              Real Exponent = Stored - 127 = 15
          Significand = 1.110 1111 0110 1111 0110 0100
          1+2^-1+2^-2+2^-4+2^-5+2^-6+2^-7+2^-9+2^-10+2^-12+
            2^-13+2^-14+2^-15+2^-17+2^-18+2^-21
          = 1.87058687210083007812
          Result = significand*2^Real Exponent = 
          = 1.87058687210083007812*2^15
          = 61295.39062499999999983616

III. Next Time:
A. Continuing Number / Data Representation