Computer Science 15-112, Fall 2011
Class Notes:  Data and Expressions


  1. Required Reading
  2. Summary of Numeric and Boolean Operators
  3. Types Affect Semantics
  4. Operator Precedence
  5. Integer division
  6. The Modulus or Remainder operator (%)
  7. Integer vs Floating-point division
  8. Approximate values of floating-point numbers
  9. "almost equal" comparison of doubles
  10. Short-circuit evaluation
  11. Truth Tables for Testing Logical Equivalence
  12. Bitwise Operators
  13. Conditional Expressions
  14. Two's Complement
  15. Some Practice

Data and Expressions

  1. Required Reading
    1. Excerpts from: Python Standard Library, Ch 5 (Built-In Types), 5.1 through 5.4
    2. Excerpts from: Python Standard Library, Ch 2 (Built-In Functions)
      (just these functions: abs, bin, bool, complex, dir, eval, float, help, hex, int, long, max, min, oct, pow, round, type)
    3. Excerpts from: Python Language Reference, Ch 3.2 (The standard type hierarchy), just until "Sequences"
    4. Python Language Reference, Ch 5.14 (Evaluation order)
    5. The Python Tutorial, Ch 3.1.1 (Numbers)
       
  2. Summary of Numeric and Boolean Operators
     
    Category Operators
    Arithmetic +, -, *, /, //, **, %, - (unary), + (unary)
    Relational <. <=, >=, >, ==, !=, <>
    Bitwise <<, >>, &, |, ^, ~
    Assignment +=, -=, *=, /=, //=, **=, %=, <<=, >>=, &=, |=, ^=
    Logical and, or, not

     

  3. Types Affect Semantics

    print 3 * 2
    print 3 * "abc"
    print 3 + 2
    print "abc" + "def"
    print 3 + "def"
     
  4. Operator Precedence
    print 2+3*4  # prints 14, not 20
    print 9**1/2 # prints 4, not 3
  5. Integer division
    print "20/3 =", (20/3)
    print " 6/3 =", ( 6/3)
    print " 5/3 =", ( 5/3)
    print " 2/3 =", ( 2/3)
    print " 0/3 =", ( 0/3)
    print "-2/3 =", (-2/3)
    print "-3/3 =", (-3/3)
    print "-4/3 =", (-4/3)
  6. The Modulus or Remainder operator (%)
    print "20%3 =", (20%3)
    print " 6%3 =", ( 6%3)
    print " 5%3 =", ( 5%3)
    print " 2%3 =", ( 2%3)
    print " 0%3 =", ( 0%3)
    print "-2%3 =", (-2%3)
    print "-3%3 =", (-3%3)
    print "-4%3 =", (-4%3)
    print " 3%0 =", ( 3%0)
  7. Integer vs Floating-point division
    print 10 / 3
    print 10.0 / 3
    print 10 / 3.0

    x = 10
    print x / 3
    print 1.0 * x / 3
    print float(x) / 3
  8. Approximate values of floating-point numbers
    d1 = 0.1 + 0.1 + 0.1
    d2 = 0.3
    print (d1 == d2) # False!
    print (d2 - d1) # -5.55111512313e-17 (tiny!)
  9. "almost equal" comparison of doubles
    d1 = 0.1 + 0.1 + 0.1
    d2 = 0.3
    print (d1 == d2) # still false, of course
    epsilon = 0.000001
    print (abs(d2 - d1) < epsilon) # True!
    Once again, using an almostEqual function (that we will write)
    
    def almostEqual(d1, d2):
        epsilon = 0.000001
        return (abs(d2 - d1) < epsilon)
    d1 = 0.1 + 0.1 + 0.1
    d2 = 0.3
    print (d1 == d2) # still false, of course
    print almostEqual(d1, d2) # True, and now packaged in a handy reusable function!
  10. Short-circuit evaluation
    x = 0
    y = 0
    print ((y != 0) and ((x/y) != 0)) # Works!
    print (((x/y) != 0) and (y != 0)) # Crashes!

    Once again, using the "or" operator

    x = 0
    y = 0
    print ((y == 0) or ((x/y) == 0)) # Works!
    print (((x/y) == 0) or (y == 0)) # Crashes!

    Yet another example:

    def isPositive(n):
        result = (n > 0)
        print "isPositive(",n,") =", result
        return result
    
    def isEven(n):
        result = (n % 2 == 0)
        print "isEven(",n,") =", result
        return result
    
    print "Test 1: isEven(-4) and isPositive(-4)"
    print (isEven(-4) and isPositive(-4)) # Calls both functions
    print "----------"
    print "Test 2: isEven(-3) and isPositive(-3)"
    print (isEven(-3) and isPositive(-3)) # Calls only one function!
  11. Truth Tables for Testing Logical Equivalence
    One of DeMorgan's Laws states:  A and B == not ((not A) or (not B))
     
    A B A and B not A not B (not A) or (not B) not ((not A) or (not B))
    0 0 0 1 1 1 0
    0 1 0 1 0 1 0
    1 0 0 0 1 1 0
    1 1 1 0 0 0 1

     

  12. Bitwise Operators
    # 0 1 1 0 = 4 + 2 = 6
    # 0 1 0 1 = 4 + 1 = 5
    
    print "6 & 5 =", (6&5)
    print "6 | 5 =", (6|5)
    print "6 ^ 5 =", (6^5)
    print "6 << 1 =", (6 << 1)
    print "6 << 2 =", (6 << 2)
    print "6 >> 1 =", (6 >> 1)
    print "~6     =", (~6)
    print "~6+1   =", (~6+1)
    print "~432+1 =", (~432+1)
    
    print "Bitwise DeMorgan's Law:  a&b == ~(~a|~b)"
    print "6 & 5 =", (6&5)
    print "~(~6|~5) =", (~(~6|~5))
  13. Conditional Expressions
    # Note: you may not use conditional expressions until we cover
    # conditional ("if") statements in a week or two.
    # They are included here, though, as they are expressions, not statements,
    # so deserve some mention in the section on expressions.
    x = 2 y = 3 if (x < 4) else 5 z = 4 if (x > 4) else 5 print x, y, z
  14. Two's Complement
    1. Optional reading (Wikipedia)
       
    2. Why?
      1. Subtraction via complement and addition (saves circuit space, back when that mattered)
      2. No problem with "negative zero"  (1000)
        (but this means there is an "extra" negative number)
      3. It's a standard (the real reason now -- most real computers are really built this way today)
         
    3. With 3 Bits
      Bits Decimal Value
      000 0
      001 1
      010 2
      011 3
      100 -4
      101 -3
      110 -2
      111 -1
      • Leftmost (most significant) bit == "sign" bit (1 = negative, 0 = non-negative)
      • For non-negatives, value == |magnitude of non-sign bits|
      • For negatives, value == -(22) + |magnitude of non-sign bits|
      • Negation:  -x == ~x+1.
        Check:
           011 = +3
           ~(011) = 100
           ~(011)+1 = 101
           101 == -3 (see table above).
        It works!
         
    4. 10's Complement
      1. How to "bit flip" in base 10?  For digit d, take ~d to mean (9-d)
      2. So, let's negate 328:
             -328 = ~(328) + 1
                  = 671 + 1
                  = 672
      3. But what does that mean?
      4. To check, let's compute 404 - 328 by instead adding 405 + (-328) (modulo 1000)
             404 - 328 = 404 + (-328)
                       = (404 + 672) % 1000
                       = 1076 % 1000
                       = 76
        It works!
         
  15. Some Practice
    # Enter these expressions and statements into the interpreter.
    # Predict the results of each line before advancing to the next line.
    # Be precise.
    
    print 3*3/4, 3/4*3, 3**3/4
    
    x = 1000*1000*1000*1000 # one trillion
    x
    print x
    type(x)
    x /= 1000*1000*1000 # divide by one billion 
    x
    x/1000
    x
    
    x = 123
    x.bit_length()
    
    import sys
    x = sys.maxint  # 2^31-1, or 2147483647
    x.bit_length()
    x
    x+1
    -x
    -(x+1)
    -x-1
    -x-2
    
    not 43
    not 43/99
    43/99 or 99/43 or 99
    
    print 0xff
    print hex(255)
    print 255 == 0xff
    print 255 == hex(255)
    
    print "-----------------"
    x = 5
    print 42 if (x == 5) else 99
    print ((x == 5) and 42) or 99
    print ((x == 5) * 42) + ((x != 5) * 99)
    print 42 + (x/6)*(99-42)
    print 42 + ((x-5)*(99-42))
    
    print "-----------------"
    x = 6
    print 42 if (x == 5) else 99
    print ((x == 5) and 42) or 99
    print ((x == 5) * 42) + ((x != 5) * 99)
    print 42 + (x/6)*(99-42)
    print 42 + ((x-5)*(99-42))

carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem