;; The first three lines of this file were inserted by DrRacket. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "2017-fall-reader.rkt" "csc104")((modname 2017W.binary-arithmetic) (compthink-settings #hash((prefix-types? . #f)))) ; Binary notation and arithmetic. ; How do we go from a decimal representation [where arithmetic is familiar to us] ; to a binary representation? ; One approach: find the largest power of 2 less than or equal to the number: (check-expect 104 (+ 64 (- 104 64))) ; Then do that for the remainder after subtracting it: (check-expect 104 (+ 64 40)) ; And so on: (check-expect 104 (+ 64 32 (- 40 32))) (check-expect 104 (+ 64 32 8)) ; Put in some “0”s for the missing powers: (check-expect 104 (+ 64 32 0 8 0 0 0)) ; Now change the powers of two to “1”s: (check-expect 104 #b1101000) ; Let's get a bit of intuition for binary notation by asking questions about a number without ; converting it to decimal notation. ; The right-most bit tells us whether the number is a multiple of two. ; I.e. whether it's even. ; The right-most digit in a decimal representation tells us whether the number is a multiple of ten. (check-expect #b110100 (/ #b1101000 2)) (check-expect #b1101000 (* 2 #b110100)) (check-expect #b1101000 (* 2 2 #b11010)) (check-expect #b1101000 (* 2 2 2 #b1101)) (check-expect (even? #b1101) #false) ; because the right-most bit is 1. (check-expect (odd? #b1101) #true) (check-expect #b1101 (+ #b1100 #b1)) (check-expect (/ 104 8) 13) (check-expect (/ #b1101000 #b1000) #b1101) ; (list 128 64 32 16 8 4 2 1) (check-expect 234 (+ 128 (- 234 128))) (check-expect 234 (+ 128 106)) (check-expect 234 (+ 128 104 2)) (check-expect 234 (+ 128 (+ 64 32 8) 2)) (check-expect 234 (+ 128 64 32 0 8 0 2 0)) (check-expect 234 #b11101010) (check-expect 235 #b11101011) (check-expect 236 (+ #b11101011 1)) (check-expect 236 (+ #b11101010 2)) (check-expect 236 (+ #b11101000 4)) (check-expect 236 (+ #b11101000 #b100)) (check-expect 236 #b11101100) ; #b11101010 ; + #b10101001 ; ------------ ; ¹¹¹ ¹ ; 110010011 (check-expect (+ #b11101010 #b10101001) #b110010011) ; × 0 1 ; ; 0 0 0 ; ; 1 0 1 ; 456 ; × 104 ; ----- ; 22 : carry ; ; 1824 ; - ; 456-- ; ----- ; 47424 ; #b11010 ; × #b11011 ; --------- ; 11010 ; 11010- ; -- ; 11010--- ; 11010---- ; --------- ; ¹¹¹¹¹ ; 1010111110 (check-expect (* #b11010 #b11011) #b1010111110) ; 104 = 2 × 52 = #b10 × #b_______ = #b_______0 ; 52 = #b_______ ; 52 = 2 × 26 = #b10 × #b______ = #b______0 ; 26 = 2 × 13 = #b_____0 ; 13 = 2 × 6 + 1 = #b____1 ; 6 = 2 × 3 = #b___0 ; 3 = 2 × 1 + 1 = #b__1 ; 1 = #b_1 #b1101000 ; number->bits : number → list-of-bits (check-expect (number->bits 104) (list 1 1 0 1 0 0 0)) (check-expect (number->bits 52) (list 1 1 0 1 0 0)) ; Full design for even numbers: (check-expect (number->bits 104) (append (number->bits (/ 104 2)) (list 0))) ; ... for odd numbers: (check-expect (number->bits 13) (append (number->bits (/ (- 13 1) 2)) (list 1))) (define (number->bits n) (cond [(zero? n) (list)] [(even? n) (append (number->bits (/ n 2)) (list 0))] [else (append (number->bits (/ (- n 1) 2)) (list 1))])) (steps [hide else append-element] (define (append-element a-list an-element) (append a-list (list an-element))) (define (number->bits n) (cond [(zero? n) (list)] [(even? n) (append-element (number->bits (/ n 2)) 0)] [else (append-element (number->bits (/ (- n 1) 2)) 1)])) (number->bits 26))