{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# AE2. Advanced Exercises" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "- [Exercise A2.1](#Exercise_A2.1)\n", "- [Exercise A2.2](#Exercise_A2.2)\n", "- [Exercise A2.3](#Exercise_A2.3)\n", "\n", "Remember that these exercises are more advanced. You are not *required* to do these, but may like to do so if you want to stretch yourself. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercise A2.1\n", "\n", "As an exercise for this, you could see if you can simulate the logical combinations `xor`, `nor` and `nand`, e.g.:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False nand False = True\n", "False nand True = True\n", "True nand False = True\n", "True nand True = False\n" ] } ], "source": [ "# nand test:\n", "# see http://en.wikipedia.org/wiki/Logical_NAND\n", "# (A nand B) is not (A and B)\n", "\n", "ABList = [(False,False),(False,True),(True,False),(True,True)]\n", "for A,B in ABList:\n", " print '%s nand %s ='%(str(A),str(B)),not (A and B)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Answer" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\tnand\tFalse\t= True\n", "False\tnand\tTrue\t= True\n", "True\tnand\tFalse\t= True\n", "True\tnand\tTrue\t= False\n" ] } ], "source": [ "\"\"\" Exercise 2.1 Scientific Computing\n", " \n", " Thu 3 Oct 2013 10:46:58 BST\n", " \n", " P. Lewis : p.lewis@ucl.ac.uk\n", " \n", " nand test\n", " \n", " see http://en.wikipedia.org/wiki/Logical_NAND\n", "\n", " (A nand B) is not (A and B)\n", " \n", " It is a modification of the code in Exercise A2.1\n", " of Scientific Computing (https://github.com/profLewis/geogg122)\n", " \n", " Edits made from original:\n", " - neatened output format\n", "\"\"\"\n", "\n", "# set up a list of tuples to loop over\n", "ABList = [(False,False),(False,True),(True,False),(True,True)]\n", "\n", "# loop over tuples and print A xor B\n", "# with tabs (\\t) for neater output\n", "for A,B in ABList:\n", " print '%s\\tnand\\t%s\\t='%(str(A),str(B)),not (A and B)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\tnor\tFalse\t= True\n", "False\tnor\tTrue\t= False\n", "True\tnor\tFalse\t= False\n", "True\tnor\tTrue\t= False\n" ] } ], "source": [ "\"\"\" Exercise 2.1 Scientific Computing\n", " \n", " Thu 3 Oct 2013 10:46:58 BST\n", " \n", " P. Lewis : p.lewis@ucl.ac.uk\n", " \n", " nor test\n", " \n", " see http://en.wikipedia.org/wiki/Logical_NOR\n", "\n", " (A nor B) is not (A or B)\n", " \n", " It is a modification of the code in Exercise A2.1\n", " of Scientific Computing (https://github.com/profLewis/geogg122)\n", " \n", " Edits made from original:\n", " - neatened output format\n", " - modified from nand to nor\n", "\"\"\"\n", "\n", "# set up a list of tuples to loop over\n", "ABList = [(False,False),(False,True),(True,False),(True,True)]\n", "\n", "# loop over tuples and print A xor B\n", "# with tabs (\\t) for neater output\n", "for A,B in ABList:\n", " print '%s\\tnor\\t%s\\t='%(str(A),str(B)),not (A or B)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\txor\tFalse\t= False\n", "False\txor\tTrue\t= True\n", "True\txor\tFalse\t= True\n", "True\txor\tTrue\t= False\n" ] } ], "source": [ "\"\"\" Exercise 2.1 Scientific Computing\n", " \n", " Thu 3 Oct 2013 10:46:58 BST\n", " \n", " P. Lewis : p.lewis@ucl.ac.uk\n", " \n", " xor test\n", " \n", " see http://en.wikipedia.org/wiki/Logical_XOR\n", "\n", " (A xor B) is (A or B) and not (A and B)\n", " \n", " It is a modification of the code in Exercise A2.1\n", " of Scientific Computing (https://github.com/profLewis/geogg122)\n", " \n", " Edits made from original:\n", " - neatened output format\n", " - modified from nand to xor\n", "\"\"\"\n", "\n", "# set up a list of tuples to loop over\n", "ABList = [(False,False),(False,True),(True,False),(True,True)]\n", "\n", "# loop over tuples and print A xor B\n", "# with tabs (\\t) for neater output\n", "for A,B in ABList:\n", " print '%s\\txor\\t%s\\t='%(str(A),str(B)),(A or B) and not (A and B)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercise A2.2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "a. Work out what the following decimal numbers are in binary:\n", "\n", " 7 \n", " 493 \n", " 127 \n", " 255 \n", " 1024 \n", "\n", " and check your result using the approach we took to confirming `101`:\n", "\n", " 101 == (1 * 2**6) + \\\n", " (1 * 2**5) + \\\n", " (0 * 2**4) + \\\n", " (0 * 2**3) + \\\n", " (1 * 2**2) + \\\n", " (0 * 2**1) + \\\n", " (1 * 2**0)\n", " \n", "b. How many bits are needed to represent each of these numbers?\n", "\n", "c. What is the largest number you could represent in: (i) a 32 bit representation; (b) a 64 bit representation?\n", "\n", "d. Recalling that there are 8 bits in a [byte](http://en.wikipedia.org/wiki/Byte), what is the largest number you could represent in: (a) a single byte; (b) two bytes? " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Answer" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**a. Work out what the following decimal numbers are in binary:**\n", "\n", "7 \n", "493 \n", "127 \n", "255 \n", "1024 " ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "7 \tin binary is 0b111\n", "493 \tin binary is 0b111101101\n", "127 \tin binary is 0b1111111\n", "255 \tin binary is 0b11111111\n", "1024 \tin binary is 0b10000000000\n" ] } ], "source": [ "for n in (7,493,127,255,1024):\n", " print n,'\\tin binary is',bin(n)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**check your result using the approach we took to confirming `101`:**\n", "\n", "Long-hand way:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "7 == (1 * 2**2) + \\\n", " (1 * 2**1) + \\\n", " (1 * 2**0)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "493 == (1 * 2**8) + \\\n", " (1 * 2**7) + \\\n", " (1 * 2**6) + \\\n", " (1 * 2**5) + \\\n", " (0 * 2**4) + \\\n", " (1 * 2**3) + \\\n", " (1 * 2**2) + \\\n", " (0 * 2**1) + \\\n", " (1 * 2**0)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "127 == (1 * 2**6) + \\\n", " (1 * 2**5) + \\\n", " (1 * 2**4) + \\\n", " (1 * 2**3) + \\\n", " (1 * 2**2) + \\\n", " (1 * 2**1) + \\\n", " (1 * 2**0)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "255 == (1 * 2**7) + \\\n", " (1 * 2**6) + \\\n", " (1 * 2**5) + \\\n", " (1 * 2**4) + \\\n", " (1 * 2**3) + \\\n", " (1 * 2**2) + \\\n", " (1 * 2**1) + \\\n", " (1 * 2**0)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1024 == (1 * 2**10)+ \\\n", " (0 * 2**9) + \\\n", " (0 * 2**8) + \\\n", " (0 * 2**7) + \\\n", " (0 * 2**6) + \\\n", " (0 * 2**5) + \\\n", " (0 * 2**4) + \\\n", " (0 * 2**3) + \\\n", " (0 * 2**2) + \\\n", " (0 * 2**1) + \\\n", " (0 * 2**0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "More automatic/advanced way (but more complicated coding):" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "7 \tin binary is 111 : 3 bits\n", "\t 1 x 2^0 = 1 x 1 \t1\n", "\t 1 x 2^1 = 1 x 2 \t3\n", "\t 1 x 2^2 = 1 x 4 \t7\n", "7 == 7? True\n", "====================================\n", "493 \tin binary is 111101101 : 9 bits\n", "\t 1 x 2^0 = 1 x 1 \t1\n", "\t 0 x 2^1 = 0 x 2 \t1\n", "\t 1 x 2^2 = 1 x 4 \t5\n", "\t 1 x 2^3 = 1 x 8 \t13\n", "\t 0 x 2^4 = 0 x 16 \t13\n", "\t 1 x 2^5 = 1 x 32 \t45\n", "\t 1 x 2^6 = 1 x 64 \t109\n", "\t 1 x 2^7 = 1 x 128 \t237\n", "\t 1 x 2^8 = 1 x 256 \t493\n", "493 == 493? True\n", "====================================\n", "127 \tin binary is 1111111 : 7 bits\n", "\t 1 x 2^0 = 1 x 1 \t1\n", "\t 1 x 2^1 = 1 x 2 \t3\n", "\t 1 x 2^2 = 1 x 4 \t7\n", "\t 1 x 2^3 = 1 x 8 \t15\n", "\t 1 x 2^4 = 1 x 16 \t31\n", "\t 1 x 2^5 = 1 x 32 \t63\n", "\t 1 x 2^6 = 1 x 64 \t127\n", "127 == 127? True\n", "====================================\n", "255 \tin binary is 11111111 : 8 bits\n", "\t 1 x 2^0 = 1 x 1 \t1\n", "\t 1 x 2^1 = 1 x 2 \t3\n", "\t 1 x 2^2 = 1 x 4 \t7\n", "\t 1 x 2^3 = 1 x 8 \t15\n", "\t 1 x 2^4 = 1 x 16 \t31\n", "\t 1 x 2^5 = 1 x 32 \t63\n", "\t 1 x 2^6 = 1 x 64 \t127\n", "\t 1 x 2^7 = 1 x 128 \t255\n", "255 == 255? True\n", "====================================\n", "1024 \tin binary is 10000000000 : 11 bits\n", "\t 0 x 2^0 = 0 x 1 \t0\n", "\t 0 x 2^1 = 0 x 2 \t0\n", "\t 0 x 2^2 = 0 x 4 \t0\n", "\t 0 x 2^3 = 0 x 8 \t0\n", "\t 0 x 2^4 = 0 x 16 \t0\n", "\t 0 x 2^5 = 0 x 32 \t0\n", "\t 0 x 2^6 = 0 x 64 \t0\n", "\t 0 x 2^7 = 0 x 128 \t0\n", "\t 0 x 2^8 = 0 x 256 \t0\n", "\t 0 x 2^9 = 0 x 512 \t0\n", "\t 1 x 2^10 = 1 x 1024 \t1024\n", "1024 == 1024? True\n", "====================================\n" ] } ], "source": [ "# loop over numbers\n", "for n in (7,493,127,255,1024):\n", " \n", " # convert decimal to binary \n", " # then convert to string and ignore 0b at start\n", " binstr = bin(n)[2:]\n", " \n", " # initialise sum as accumulator\n", " sum = 0\n", " \n", " # how many bits in this case?\n", " nBits = len(binstr)\n", " print n,'\\tin binary is',binstr,\": %d bits\"%nBits\n", " \n", " # loop over each bit\n", " for c in xrange(nBits):\n", " \n", " # extract the bit and exponent\n", " bit = int(binstr[-(c+1)])\n", " exp = 2**c\n", " sum += exp * bit\n", " print '\\t %d x 2^%d = %d x %d \\t%d'%(bit,c,bit,exp,sum)\n", " \n", " print \"%d == %d?\"%(n,sum),n == sum \n", " print \"====================================\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you enjoyed this part of the exercise ;-) , you could repeat this part of it, but using base 8 (octal) and or base 16 (hexadecimal), which you will often come across in computing. We might use octal e.g. in unix file permissions, or hexadecimal more widely in memory addresses (because it would be too long a number in binary!).\n", "\n", "e.g.:\n" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "493 \tin octal is 755 : 3 octets\n", "\t 5 x 8^0 = 5 x 1 \t5\n", "\t 5 x 8^1 = 5 x 8 \t45\n", "\t 7 x 8^2 = 7 x 64 \t493\n", "493 == 493? True\n", "====================================\n" ] } ], "source": [ "n = 493\n", "# N.B, no 0b or 0x part on the string for octal, just a \n", "# leading 0\n", "octstr = oct(n)[1:]\n", "sum = 0\n", "# how many octets in this case? (assuming thats the right word)\n", "nOct = len(octstr)\n", "print n,'\\tin octal is',octstr,\": %d octets\"%nOct\n", " \n", "# loop over each octets\n", "for c in xrange(nOct):\n", " # extract the octet and exponent\n", " octet = int(octstr[-(c+1)])\n", " exp = 8**c\n", " sum += exp * octet\n", " print '\\t %d x 8^%d = %d x %d \\t%d'%(octet,c,octet,exp,sum)\n", "print \"%d == %d?\"%(n,sum),n == sum \n", "print \"====================================\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**b. How many bits are needed to represent each of these numbers?**" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "111 3 bits\n", "111101101 9 bits\n", "1111111 7 bits\n", "11111111 8 bits\n", "10000000000 11 bits\n" ] } ], "source": [ "# bin() converts to binary, but really its a string\n", "# the first 2 characters of which are '0b'\n", "# so find the length of the string other than the first two\n", "# characters\n", "\n", "for n in (7,493,127,255,1024):\n", " binstr = bin(n)[2:]\n", " print binstr,len(binstr),'bits'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**c. What is the largest number you could represent in: (i) a 32 bit representation; (b) a 64 bit representation?**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In an *unsigned* integer representation, the largest number would be one with `1` in all bit fields.\n", "\n", "We *could* add this up, but it's faster to notice that this is one less than two to the power of the number of bits, e.g. the largest number with 8 bits is `2^8 - 1`:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "the largest (unsigned) integer with 8 bits (1 byte) is 255\n" ] } ], "source": [ "print \"the largest (unsigned) integer with 8 bits (1 byte) is\",2**8 -1" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "the largest (unsigned) integer with 32 bits is 4294967295\n", "the largest (unsigned) integer with 64 bits is 18446744073709551615\n" ] } ], "source": [ "print \"the largest (unsigned) integer with 32 bits is\",2**32 -1\n", "print \"the largest (unsigned) integer with 64 bits is\",2**64 -1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sometimes, a *signed* integer representation is used, in which case the leftmost bit (usually) of the bit field is used to represent the *sign* (`0` meaning `+ve` and `1` meaning `-ve`), so e.g.:\n", "\n", "`011` would be +7 in decimal but \n", "`111` would be -7 in decimal \n", "\n", "This means that there is one fewer bit to represent the magnitude of the number, so e.g. with 8 bits (one byte) you have one bit for the sign, and 7 bits for magnitude:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "the largest (signed) integer with 8 bits (1 byte) is 127\n", "the smallest (signed) integer with 8 bits (1 byte) is -127\n" ] } ], "source": [ "print \"the largest (signed) integer with 8 bits (1 byte) is\",+2**(8-1) -1\n", "print \"the smallest (signed) integer with 8 bits (1 byte) is\",-2**(8-1) +1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Interestingly, in a signed integer representation, there are two numbers that represent zero:\n", "\n", " 000\n", " 100\n", " \n", "which effectively mean `+0` and `-0`. In that sense, the signed representation is a little wasteful (but you only lose one number!)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**d. Recalling that there are 8 bits in a [byte](http://en.wikipedia.org/wiki/Byte), what is the largest number you could represent in: (a) a single byte; (b) two bytes? **" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So, one byte is 8 bits.\n", "\n", "As we saw above, for an unsigned representation this can have integers from `0` to `255`.\n", "\n", "For a signed representation this can have integers from `-127` to `+127`.\n", "\n", "Two bytes is 16 bits, so:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "the largest (unsigned) integer with 16 bits (2 bytes) is 65535\n", "the largest (signed) integer with 16 bits (2 bytes) is 32767\n", "the smallest (signed) integer with 16 bits (2 bytes) is -32767\n" ] } ], "source": [ "print \"the largest (unsigned) integer with 16 bits (2 bytes) is\",2**16 -1\n", "print \"the largest (signed) integer with 16 bits (2 bytes) is\",+2**(16-1) -1\n", "print \"the smallest (signed) integer with 16 bits (2 bytes) is\",-2**(16-1) +1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercise A2.3" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "qa1 0b1\n", "qa2 0b1\n", "qa3 0b1\n", "qa4 0b11\n", "qa5 0b111\n" ] } ], "source": [ "qa = 0b11111111\n", "\n", "qa1 = (qa & 0b00000001) >> 0 # bit 0\n", "qa2 = (qa & 0b00000010) >> 1 # bit 1\n", "qa3 = (qa & 0b00000100) >> 2 # bit 2\n", "qa4 = (qa & 0b00011000) >> 3 # bit 3-4\n", "qa5 = (qa & 0b11100000) >> 5 # bit 5-7\n", "\n", "print 'qa1',bin(qa1)\n", "print 'qa2',bin(qa2)\n", "print 'qa3',bin(qa3)\n", "print 'qa4',bin(qa4)\n", "print 'qa5',bin(qa5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Develop some code to repeat the QA bit masking done above, but make the code generate the bit masks itself from knowledge of the first and last of the bit fields you require (assuming they are sequential).\n", "\n", "If possible, do this in a function.\n", "\n", "Demonstrate its operation with several example bit masks." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Answer" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One way to this elegantly is to use the left shift to generate the bit masks.\n", "\n", "e.g. to put a `1` in bit 2:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0b100\n" ] } ], "source": [ "mask2 = 0b1 << 2\n", "print bin(mask2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or to fill fields 3-4:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0b11000\n" ] } ], "source": [ "mask3 = 0b11 << 3\n", "print bin(mask3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "An easier way though is to right shift the qa and perform a bitwise and with the mask:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0b11\n" ] } ], "source": [ "qa = 0b00011000\n", "mask3 = 0b11\n", "print bin((qa >> 3) & mask3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We need to consider how to pass the information through to this operation.\n", "\n", "One way would be to use a `dict` with the `key` as the starting value of the bit field and the `value` as the end:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fields = {0:0, 1:1, 2:2, 3:4, 5:7}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We access these as:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 0\n", "1 1\n", "2 2\n", "3 4\n", "5 7\n" ] } ], "source": [ "for start,finish in fields.items():\n", " print start,finish" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then form an integer which is `2^n -1`, where `n` is the (inclusive) length from `start` to `finish`" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0b11\n" ] } ], "source": [ "# a test qa with only required bits\n", "qa = 0b00011000\n", "start = 3\n", "finish = 4\n", "\n", "print bin(2**(finish-start+1)-1)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 0 0b1\n", "1 1 0b1\n", "2 2 0b1\n", "3 4 0b11\n", "5 7 0b111\n" ] } ], "source": [ "# qa with all bits filled\n", "qa = 0b11111111\n", "\n", "for start,finish in fields.items():\n", " mask = 2**(finish-start+1)-1\n", " print start,finish,bin(mask)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "so now we right shift the `qa` by `start` and perform a bitwise and (`&`) with the mask:" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0b11\n" ] } ], "source": [ "start = 3\n", "finish = 4\n", "qa = 0b00011000\n", "\n", "mask = (2**(finish-start+1)-1)\n", "maskedQA = (qa >> start) & mask\n", "print bin(maskedQA)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can combine all of these ideas:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 0 0b1\n", "1 1 0b1\n", "2 2 0b1\n", "3 4 0b11\n", "5 7 0b111\n" ] } ], "source": [ "fields = {0:0, 1:1, 2:2, 3:4, 5:7}\n", "\n", "# qa with all bits filled\n", "qa = 0b11111111\n", "\n", "for start,finish in fields.items():\n", " mask = (2**(finish-start+1)-1)\n", " maskedQA = (qa >> start) & mask \n", " print start,finish,bin(maskedQA)\n" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [], "source": [ "\"\"\"Exercise 2.1 Scientific Computing\n", " \n", " Thu 3 Oct 2013 10:46:58 BST\n", " \n", " P. Lewis : p.lewis@ucl.ac.uk\n", " \n", " bit mask test\n", " \n", " Original code\n", " \n", "\"\"\"\n", "def maskedQA(qa, fields = {0:0, 1:1, 2:2, 3:4, 5:7}):\n", " \"\"\"Return a dictionary of masked QA bit fields\n", " \n", " Inputs:\n", " qa -- QA to be masked\n", " \n", " Keyword arguments:\n", " fields -- bit field dictionary (default {0:0, 1:1, 2:2, 3:4, 5:7})\n", " Here, the key is the start bit of a mask and the value\n", " the end bit (inclusive).\n", " \n", " Returns:\n", " Masked QA in dictionary with same keys as fields\n", " \"\"\"\n", " \n", " maskedQAs = {}\n", " \n", " for start,finish in fields.items():\n", " mask = (2**(finish-start+1)-1)\n", " maskedQAs[start] = (qa >> start) & mask \n", "\n", " return maskedQAs\n" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function maskedQA in module __main__:\n", "\n", "maskedQA(qa, fields={0: 0, 1: 1, 2: 2, 3: 4, 5: 7})\n", " Return a dictionary of masked QA bit fields\n", " \n", " Inputs:\n", " qa -- QA to be masked\n", " \n", " Keyword arguments:\n", " fields -- bit field dictionary (default {0:0, 1:1, 2:2, 3:4, 5:7})\n", " Here, the key is the start bit of a mask and the value\n", " the end bit (inclusive).\n", " \n", " Returns:\n", " Masked QA in dictionary with same keys as fields\n", "\n" ] } ], "source": [ "help(maskedQA)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 0b1\n", "1 1 0b1\n", "2 1 0b1\n", "3 3 0b11\n", "5 7 0b111\n" ] } ], "source": [ "# testing\n", "\n", "qaDict = maskedQA(0b11111111)\n", "for k in qaDict.keys():\n", " print k,qaDict[k],bin(qaDict[k])" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 0b1\n", "1 0 0b0\n", "2 1 0b1\n", "3 2 0b10\n", "5 2 0b10\n" ] } ], "source": [ "qaDict = maskedQA(0b01010101)\n", "for k in qaDict.keys():\n", " print k,qaDict[k],bin(qaDict[k])" ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 0 }