#import "@local/handout:0.1.0": * = Integers #definition() A _bit string_ is a string of binary digits. \ In this handout, we'll denote bit strings with the prefix `0b`. \ #note[This prefix is only notation---it is _not_ part of the string itself.] \ For example, $1001$ is the number "one thousand and one," while $#text([`0b1001`])$ is the string of bits "1 0 0 1". #v(2mm) We will separate long bit strings with underscores for readability. \ Underscores have no meaning: $#text([`0b1111_0000`]) = #text([`0b11110000`])$. #problem() What is the value of the following bit strings, if we interpret them as integers in base 2? - `0b0001_1010` - `0b0110_0001` #solution([ - $#text([`0b0001_1010`]) = 2 + 8 + 16 = 26$ - $#text([`0b0110_0001`]) = 1 + 32 + 64 = 95$ ]) #v(1fr) #definition() We can interpret a bit string in any number of ways. \ One such interpretation is the _unsigned integer_, or `uint` for short. \ `uint`s allow us to represent positive (hence "unsigned") integers using 32-bit strings. #v(2mm) The value of a `uint` is simply its value as a binary number: - $#text([`0b00000000_00000000_00000000_00000000`]) = 0$ - $#text([`0b00000000_00000000_00000000_00000011`]) = 3$ - $#text([`0b00000000_00000000_00000000_00100000`]) = 32$ - $#text([`0b00000000_00000000_00000000_10000010`]) = 130$ #problem() What is the largest number we can represent with a 32-bit `uint`? #solution([ $#text([`0b11111111_11111111_11111111_11111111`]) = 2^(32)-1$ ]) #v(1fr) #pagebreak() #problem() Find the value of each of the following 32-bit unsigned integers: - `0b00000000_00000000_00000101_00111001` - `0b00000000_00000000_00000001_00101100` - `0b00000000_00000000_00000100_10110000` #hint([The third conversion is easy---look carefully at the second.]) #instructornote[ Consider making a list of the powers of two $>= 1024$ on the board. ] #solution([ - $#text([`0b00000000_00000000_00000101_00111001`]) = 1337$ - $#text([`0b00000000_00000000_00000001_00101100`]) = 300$ - $#text([`0b00000000_00000000_00000010_01011000`]) = 1200$ Notice that the third int is the second shifted left twice (i.e, multiplied by 4) ]) #v(1fr) #definition() In general, fast division of `uints` is difficult#footnote([One may use repeated subtraction, but this isn't efficient.]). \ Division by powers of two, however, is incredibly easy: \ To divide by two, all we need to do is shift the bits of our integer right. #v(2mm) For example, consider $#text[`0b0000_0110`] = 6$. \ If we insert a zero at the left end of this string and delete the zero at the right \ (thus "shifting" each bit right), we get `0b0000_0011`, which is 3. \ #v(2mm) Of course, we lose the remainder when we right-shift an odd number: \ $9$ shifted right is $4$, since `0b0000_1001` shifted right is `0b0000_0100`. #problem() Right shifts are denoted by the `>>` symbol: \ $#text[`00110`] #text[`>>`] n$ means "shift `0b0110` right $n$ times." \ Find the value of the following: - $12 #text[`>>`] 1$ - $27 #text[`>>`] 3$ - $16 #text[`>>`] 8$ #note[Naturally, you'll have to convert these integers to binary first.] #solution[ - $12 #text[`>>`] 1 = 6$ - $27 #text[`>>`] 3 = 3$ - $16 #text[`>>`] 8 = 0$ ] #v(1fr)