CS 227 Lecture -*- Outline -*- * Binary Numbers (5.4) Numbers represented (stored) in binary easier/cheaper to build than direct decimal numbers fewer wasted states, and carrys in addition are more regular ** Memory (RAM) many cells (bytes) each cell like a row of switches on = 1, off = 0 (draw picture) *** Bits information in each switch is a *bit* (b) *** Bytes eight bits make a *byte* of information (B) memory usually measured in bytes (1 MB) 2^8 = 256 different values represented by a byte e.g., the numbers 0 -- 255 ** Numbers -- will now describe how unsigned numbers are represented in binary (or other bases) in a computer -- important for low level operations in other languages (e.g., C or C++) -- important for hardware design -- important for debugging in some languages *** Decimal digits are placeholders for powers of 10 -------------- DECIMAL NOTATION 473 = 4 (10^2) + 7 (10^1) + 3 (10^0) -------------- The number 10 is the *base* of the decimal notation We say that 473 is written in *base 10* Note similarity to polynomials -------------- 473 = value of 4 x^2 + 7 x^1 + 3 x^0 (at x = 10) -------------- Use the same placeholder/polynomial idea for other bases. ** Binary -------------- BINARY NOTATION 473 decimal = 111011001 binary = 1(2^8) + 1(2^7) + 1(2^6) + 0(2^5) + 1(2^4) + 1(2^3) + 0(2^2) + 0(2^1) + 1(2^0) = 1 x^8 + 1 x^7 + 1 x^6 + 0 x^5 + 1 x^4 + 1 x^3 + 0 x^2 + 0 x^1 + 1 x^0 (at x = 2) -------------- *** digits->poly -- want a procedure that takes a list of digits (placeholders) and returns a polynomial -- won't do to simply call the list a poly, because that does not work with all representations of polynomials -------------- (digits->poly '(1)) = (poly-cons 0 1 the-zero-poly) (digits->poly '(1 0)) = (poly-cons 1 1 (poly-cons 0 0 the-zero-poly)) digits->poly: (-> ((nonempty-list number)) poly) -------------- want to do flat recursion over the nonempty list how to get (digits->poly ls) from (car ls), (cdr ls) and (digits->poly (cdr ls)) ? use (poly-cons (length (cdr ls)) (car ls) (digits->poly (cdr ls))) what is the base case? (null? (cdr ls)) need to return (poly-cons O (car ls) the-zero-poly) -------------- (define digits->poly (lambda (ls) ; REQUIRES: ls is not empty (if (null? (cdr ls)) (poly-cons 0 (car ls) the-zero-poly) (poly-cons (length (cdr ls)) (car ls) (digits->poly (cdr ls)) )))) -------------- It is inefficient to compute the length so many times. So the program in the book uses letrec to define a helping procedure that avoids this. -------------- (define digits->poly (lambda (digit-list) ; REQUIRES: digit-list is not empty (letrec ((make-poly (lambda (deg ls) ; REQUIRES: (+ 1 deg) ; = (length ls) (if (zero? deg) (poly-cons deg (car ls) the-zero-poly) (poly-cons deg (car ls) (make-poly (sub1 deg) (cdr ls))))))) (make-poly (sub1 (length digit-list)) digit-list)))) -------------- Program 5.16 in the book does more error checking and is based on flat recursion over general lists. *** binary->decimal conversion to decimal is now easy, just evaluate the polynomial at 2. -------------- ;; Program 5.17 (define binary->decimal ; TYPE: (-> ((list binary-digit)) ; integer) (lambda (digit-list) (poly-value (digits->poly digit-list) 2))) -------------- you should be able to do this *by hand* Q: what is 11011 base 2 in decimal? *** poly->digits -- there is an excellent explanation of the procedure (5.18) in the book. -- show what it does *** conversion to binary want to get list of binary digits -------------- CONVERSION TO BINARY (decimal->binary 1) = (1) (decimal->binary 4) = (1 0 0) -------------- does not seem obvious, so we have to do some planning. Helps to think of the binary form as a polynomial. -------------- 4 = 1(2^2) + 0(2^1) + 0(2^0) -------------- Now recall Horner's rule. -------------- 4 = ((1)2 + 0)2 + 0 -------------- Note that 0 is the remainder of 4 divided by 2. In general -------------- if (decimal->binary q) = (a[n] ... a[0]) then q = (...((a[n])2 + a[n-1])2 + ... + a[1])2 + a[0] -------------- So now we look for a recursive (1 step) expression Q: what is a[0] in terms of q and 2? -------------- where (quotient q 2) = (...((a[n])2 + a[n-1])2 + ... + a[1]) and (remainder q 2) = a[0] -------------- Here is how it works with hand -------------- CONVERTING BY HAND Quotient Remainder 19 9 1 4 1 2 0 1 0 0 1 So 19 = 10011 binary -------------- read from the bottom In class exercise: have them try 41 (=101001 binary) -------------- <binary definition>>= (define decimal->binary ; TYPE: (-> (integer) ; (list binary-digit)) (lambda (num) ; REQUIRES: num is not negative (letrec (<bin def>>) (poly->digits (dec->bin num 0))))) <bin def>>= (dec->bin ; TYPE: (-> (integer integer) poly) (lambda (n deg) ; REQUIRES: deg >= 0 and n >= 0 ; ENSURES: (poly-value result 2) = n (if (zero? n) (make-term 0 0) (p+ (make-term deg (remainder n 2)) (dec->bin (quotient n 2) (add1 deg)))))) @ -------------- Note: Exercise 5.20 has the faster version that does not make a polynomial Describe why the ENSURES clause holds, based on the earlier discussion. ** Other number systems (bases) *** octal -- base 8 *** hexadecimal -- base 16 uses digits 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F -------------- OCTAL AND HEXADECIMAL 15 decimal = 17 octal = F hexadecimal 19 decimal = 23 octal = 13 hexadecimal 65 decimal = 101 octal = 41 hexadecimal -------------- exercise for students: convert 52141 to octal and hex (= CBAD)