# Boolean questions Create the following variables. ``` a = Bits("11110000") b = Bits("10101010") ``` For each of the following bytes, give an equivalent expression which uses only `a`, `b`, and bit operators. The answers to the first two questions are given. 1. 01010101 ~b 2. 00000101 ~a & ~b 3. 00000001 a >> 7 4. 10000000 a << 3 5. 01010000 (a & b) >>1 6. 00001010 (~a) & b 7. 01010000 #this is the same as #5... ((~a) & b) << 3 8. 10101011 (a >> 7) | b ## Integer questions These questions are difficult! Try exploring ideas with `Bits` in Terminal, a paper and pencil, and a whiteboard. And definitely talk with others. 9. If `a` represents a positive integer, and `one = Bits(1, length=len(a))`, give an expression equivalent to `-a`, but which does not use negation. ~a + Bits(1, length = len(a)) 10. It is extremely easy to double a binary number: just shift all the bits to the left. (`a << 1` is twice `a`.) Explain why this trick works. From a math approach, binary is writing numbers in base 2, so each 0/1 represents a power of 2, increasing as you go to the left. For example, 00000101 = 5, beacuse its 2^2 + 2^0 = 4 + 1 = 5. So every time you shift the binary numbers once to the left, you are introducing a new power of 2, or effectively multiplying by 2. 11. Consider the following: ``` >>> hundred = Bits(100, 8) >>> hundred 01100100 >>> (hundred + hundred) 11001000 >>> (hundred + hundred).int -56 ``` Apparently 100 + 100 = -56. What's going on here? Since we are only using 8 bits, the highest possible positive number we can represent is 127 (just shy of 2^7, which is 128, because we can only represent up to 2^7 with 8 digits). When you do the bitwise addition, you end up with a 1 as the first bit, which signals to the computer that this is a negative number. In other words, you can't do proper integer addition in 8 bits with a positive result higher than 127, because it cannot be represented in 8 bits. 12. What is the bit representation of negative zero? Explain your answer. I was a bit hesitant about this one, because my math brain tells me that there is no such thing as negative 0, so I tried Bits(0,8) and Bits(-0,8) and turns out I was right, they are both 00000000. 13. What's the largest integer that can be represented in a single byte? Explain your reasoning. Oh I already did this one! It's 127, see my reasoning above. 14. What's the smallest integer that can be represented in a single byte? Explain your reasoning. -128, similarly to above. This is represented by 10000000, which is effectively the inverse of 127, but minus 1 (which are the steps for finding the negative) 15. What's the largest integer that can be represented in `n` bits? Explain your reasoning. (2^(n-1))-1. Similar reasoning to how I got 127, because it will be one less than the highest power of 2 made from the given powers. Yay math questions! ## Text questions 16. Look at the bits for a few different characters using the `utf8` encoding. You will notice they have different bit lengths: ``` >>> Bits('a', encoding='utf8') 01100001 >>> Bits('ñ', encoding='utf8') 1100001110110001 >>> Bits('♣', encoding='utf8') 111000101001100110100011 >>> Bits('😍', encoding='utf8') 11110000100111111001100010001101 ``` When it's time to decode a sequence of utf8-encoded bits, the decoder somehow needs to decide when it has read enough bits to decode a character, and when it needs to keep reading. For example, the decoder will produce 'a' after reading 8 bits but after reading the first 8 bits of 'ñ', the decoder realizes it needs to read 8 more bits. Make a hypothesis about how this could work. There must be some sort of pattern to the way characters are encoded in the first place. It must have something to do with how many zeros are next to each other, like maybe there's a rule that there can't be more than 4 zeros in a row in a given byte? So when it sees more than that in a byte, it stops and decides to code up until that point? I decided to look this up after I hypothesized because I was struggling to find a pattern, and the actual way it works is super cool! It uses the first few digits of the first byte to determine how many bytes long the character is, and then it reads only that many!