Hi readers,
I wrote this post yesterday:
Analyse this Python code snippet
I was initially going to give the solution (to the question asked in that post) today, but then realized that I posted it at the weekend. So, to give a bit of time for anyone to attempt it, including some of my programming students, I decided to post the solution early next week.
But in the meantime, inspired some Q&A in a class I taught, I had the idea of creating this simple program to find the the number of bits needed to represent integers of various sizes (0 to 256, specifically, though the code can easily be modified to do it for any size of int). Note that this is the calculation of the minimum number of bits needed to represent some integers per se, not necessarily the number of bits that Python or any other language actually uses to store those same integers, which can be more than the minimum. This is because, at least in the case of Python, being a dynamic language, most data types have more capabilities than just being data - e.g. ints in Python are objects, so they incur some overhead for being objects (instances of classes, such as having a dictionary of attributes, and so on). The other reason is that data objects in dynamic languages often take up extra pre-allocated space, to store some metadata or to allow for future expansion in the size of the value being stored - e.g. that may or not apply in the case of ints, but it can in the case of lists.
(See this earlier post by me: Exploring sizes of data types in Python for more on this topic.)
Note: the level of this post is targeted towards relative beginners to programming, who might not be too familiar with computer representation of numbers, or even towards somewhat experienced programmers, who are not familiar with that topic either (I've come across some). Believe it or not, I've come across people (ex-colleagues in some cases, as well as others, and developers as well as system administrators) who did not know that a compiled binary for one processor will usually not run on another type of processor [1], even though they may be running the same OS (such as Unix), because their (processor) instructions sets are different. (What's an instruction set? - some of them might ask.) This is like expecting a person who only knows language A to understand something spoken in language B - impossible, at least without some source of help, be it another person or a dictionary.
Having some knowledge in these areas (i.e. system internals or under-the-hood stuff, even at a basic level) is quite useful to have, and almost needed, for many real-life situations, ranging from things like choosing an appropriate data representation for your data, finding and fixing bugs quicker, system integration, data reading / writing / transformation / conversion, to bigger-picture issues like system performance and portability.
[1] Though there are exceptions to that these days, such as fat binaries.
Anyway, end of rant :)
I chose 256 as the upper limit because it is the size (+1) of the highest unsigned integer that can be stored in a single byte, and because values in the range 0 to 255 or 256 are very commonly used in low-level code, such as bit manipulation, assembly or machine language, C, some kinds of data processing (e.g. of many binary file formats), and so on. Of course values of word size (2 bytes / 16 bits) or double-word (4 bytes / 32 bits) are also often used in those areas, but the program can be modified to handle them too.
If you want to get a preview (and a clue) about what is coming up, check this snippet and its output first:
>>> for item in (0, 1, 2, 4, 8, 16): ... print item.bit_length() ... 0 1 2 3 4 5Hint: Notice that those are all powers of 2 in the tuple above, and correlate that fact with the output values.
Here is the program to find the number of bits needed to store an integer, and its binary representation (Python):
# int_bit_length_and_binary_repr.py # Purpose: For integers from 0 to 256, print the number of # bits needed to represent them, and their values in binary. # Author: Vasudev Ram # Website: https://vasudevram.github.io # Product store on Gumroad: https://gumroad.com/vasudevram # Blog: https://jugad2.blogspot.com # Twitter: @vasudevram for an_int in range(0, 256 + 1): print an_int, "takes", an_int.bit_length(), "bits to represent,", print "and equals", bin(an_int), "in binary"
Before showing the output (because it is long, since I've shown all 257 rows of it:
If you found this post informative, you may also be interested in this earlier one on a related topic:
Converting numeric strings to integers with handrolled code
(I didn't remember to say it in that earlier post, but the image at the top of it is of a roti being rolled out with a rolling pin:)
And here is the output when I run the program:
$ python int_bit_length_and_binary_repr.py 0 takes 0 bits to represent, and equals 0b0 in binary 1 takes 1 bits to represent, and equals 0b1 in binary 2 takes 2 bits to represent, and equals 0b10 in binary 3 takes 2 bits to represent, and equals 0b11 in binary 4 takes 3 bits to represent, and equals 0b100 in binary 5 takes 3 bits to represent, and equals 0b101 in binary 6 takes 3 bits to represent, and equals 0b110 in binary 7 takes 3 bits to represent, and equals 0b111 in binary 8 takes 4 bits to represent, and equals 0b1000 in binary 9 takes 4 bits to represent, and equals 0b1001 in binary 10 takes 4 bits to represent, and equals 0b1010 in binary 11 takes 4 bits to represent, and equals 0b1011 in binary 12 takes 4 bits to represent, and equals 0b1100 in binary 13 takes 4 bits to represent, and equals 0b1101 in binary 14 takes 4 bits to represent, and equals 0b1110 in binary 15 takes 4 bits to represent, and equals 0b1111 in binary 16 takes 5 bits to represent, and equals 0b10000 in binary 17 takes 5 bits to represent, and equals 0b10001 in binary 18 takes 5 bits to represent, and equals 0b10010 in binary 19 takes 5 bits to represent, and equals 0b10011 in binary 20 takes 5 bits to represent, and equals 0b10100 in binary 21 takes 5 bits to represent, and equals 0b10101 in binary 22 takes 5 bits to represent, and equals 0b10110 in binary 23 takes 5 bits to represent, and equals 0b10111 in binary 24 takes 5 bits to represent, and equals 0b11000 in binary 25 takes 5 bits to represent, and equals 0b11001 in binary 26 takes 5 bits to represent, and equals 0b11010 in binary 27 takes 5 bits to represent, and equals 0b11011 in binary 28 takes 5 bits to represent, and equals 0b11100 in binary 29 takes 5 bits to represent, and equals 0b11101 in binary 30 takes 5 bits to represent, and equals 0b11110 in binary 31 takes 5 bits to represent, and equals 0b11111 in binary 32 takes 6 bits to represent, and equals 0b100000 in binary 33 takes 6 bits to represent, and equals 0b100001 in binary 34 takes 6 bits to represent, and equals 0b100010 in binary 35 takes 6 bits to represent, and equals 0b100011 in binary 36 takes 6 bits to represent, and equals 0b100100 in binary 37 takes 6 bits to represent, and equals 0b100101 in binary 38 takes 6 bits to represent, and equals 0b100110 in binary 39 takes 6 bits to represent, and equals 0b100111 in binary 40 takes 6 bits to represent, and equals 0b101000 in binary 41 takes 6 bits to represent, and equals 0b101001 in binary 42 takes 6 bits to represent, and equals 0b101010 in binary 43 takes 6 bits to represent, and equals 0b101011 in binary 44 takes 6 bits to represent, and equals 0b101100 in binary 45 takes 6 bits to represent, and equals 0b101101 in binary 46 takes 6 bits to represent, and equals 0b101110 in binary 47 takes 6 bits to represent, and equals 0b101111 in binary 48 takes 6 bits to represent, and equals 0b110000 in binary 49 takes 6 bits to represent, and equals 0b110001 in binary 50 takes 6 bits to represent, and equals 0b110010 in binary 51 takes 6 bits to represent, and equals 0b110011 in binary 52 takes 6 bits to represent, and equals 0b110100 in binary 53 takes 6 bits to represent, and equals 0b110101 in binary 54 takes 6 bits to represent, and equals 0b110110 in binary 55 takes 6 bits to represent, and equals 0b110111 in binary 56 takes 6 bits to represent, and equals 0b111000 in binary 57 takes 6 bits to represent, and equals 0b111001 in binary 58 takes 6 bits to represent, and equals 0b111010 in binary 59 takes 6 bits to represent, and equals 0b111011 in binary 60 takes 6 bits to represent, and equals 0b111100 in binary 61 takes 6 bits to represent, and equals 0b111101 in binary 62 takes 6 bits to represent, and equals 0b111110 in binary 63 takes 6 bits to represent, and equals 0b111111 in binary 64 takes 7 bits to represent, and equals 0b1000000 in binary 65 takes 7 bits to represent, and equals 0b1000001 in binary 66 takes 7 bits to represent, and equals 0b1000010 in binary 67 takes 7 bits to represent, and equals 0b1000011 in binary 68 takes 7 bits to represent, and equals 0b1000100 in binary 69 takes 7 bits to represent, and equals 0b1000101 in binary 70 takes 7 bits to represent, and equals 0b1000110 in binary 71 takes 7 bits to represent, and equals 0b1000111 in binary 72 takes 7 bits to represent, and equals 0b1001000 in binary 73 takes 7 bits to represent, and equals 0b1001001 in binary 74 takes 7 bits to represent, and equals 0b1001010 in binary 75 takes 7 bits to represent, and equals 0b1001011 in binary 76 takes 7 bits to represent, and equals 0b1001100 in binary 77 takes 7 bits to represent, and equals 0b1001101 in binary 78 takes 7 bits to represent, and equals 0b1001110 in binary 79 takes 7 bits to represent, and equals 0b1001111 in binary 80 takes 7 bits to represent, and equals 0b1010000 in binary 81 takes 7 bits to represent, and equals 0b1010001 in binary 82 takes 7 bits to represent, and equals 0b1010010 in binary 83 takes 7 bits to represent, and equals 0b1010011 in binary 84 takes 7 bits to represent, and equals 0b1010100 in binary 85 takes 7 bits to represent, and equals 0b1010101 in binary 86 takes 7 bits to represent, and equals 0b1010110 in binary 87 takes 7 bits to represent, and equals 0b1010111 in binary 88 takes 7 bits to represent, and equals 0b1011000 in binary 89 takes 7 bits to represent, and equals 0b1011001 in binary 90 takes 7 bits to represent, and equals 0b1011010 in binary 91 takes 7 bits to represent, and equals 0b1011011 in binary 92 takes 7 bits to represent, and equals 0b1011100 in binary 93 takes 7 bits to represent, and equals 0b1011101 in binary 94 takes 7 bits to represent, and equals 0b1011110 in binary 95 takes 7 bits to represent, and equals 0b1011111 in binary 96 takes 7 bits to represent, and equals 0b1100000 in binary 97 takes 7 bits to represent, and equals 0b1100001 in binary 98 takes 7 bits to represent, and equals 0b1100010 in binary 99 takes 7 bits to represent, and equals 0b1100011 in binary 100 takes 7 bits to represent, and equals 0b1100100 in binary 101 takes 7 bits to represent, and equals 0b1100101 in binary 102 takes 7 bits to represent, and equals 0b1100110 in binary 103 takes 7 bits to represent, and equals 0b1100111 in binary 104 takes 7 bits to represent, and equals 0b1101000 in binary 105 takes 7 bits to represent, and equals 0b1101001 in binary 106 takes 7 bits to represent, and equals 0b1101010 in binary 107 takes 7 bits to represent, and equals 0b1101011 in binary 108 takes 7 bits to represent, and equals 0b1101100 in binary 109 takes 7 bits to represent, and equals 0b1101101 in binary 110 takes 7 bits to represent, and equals 0b1101110 in binary 111 takes 7 bits to represent, and equals 0b1101111 in binary 112 takes 7 bits to represent, and equals 0b1110000 in binary 113 takes 7 bits to represent, and equals 0b1110001 in binary 114 takes 7 bits to represent, and equals 0b1110010 in binary 115 takes 7 bits to represent, and equals 0b1110011 in binary 116 takes 7 bits to represent, and equals 0b1110100 in binary 117 takes 7 bits to represent, and equals 0b1110101 in binary 118 takes 7 bits to represent, and equals 0b1110110 in binary 119 takes 7 bits to represent, and equals 0b1110111 in binary 120 takes 7 bits to represent, and equals 0b1111000 in binary 121 takes 7 bits to represent, and equals 0b1111001 in binary 122 takes 7 bits to represent, and equals 0b1111010 in binary 123 takes 7 bits to represent, and equals 0b1111011 in binary 124 takes 7 bits to represent, and equals 0b1111100 in binary 125 takes 7 bits to represent, and equals 0b1111101 in binary 126 takes 7 bits to represent, and equals 0b1111110 in binary 127 takes 7 bits to represent, and equals 0b1111111 in binary 128 takes 8 bits to represent, and equals 0b10000000 in binary 129 takes 8 bits to represent, and equals 0b10000001 in binary 130 takes 8 bits to represent, and equals 0b10000010 in binary 131 takes 8 bits to represent, and equals 0b10000011 in binary 132 takes 8 bits to represent, and equals 0b10000100 in binary 133 takes 8 bits to represent, and equals 0b10000101 in binary 134 takes 8 bits to represent, and equals 0b10000110 in binary 135 takes 8 bits to represent, and equals 0b10000111 in binary 136 takes 8 bits to represent, and equals 0b10001000 in binary 137 takes 8 bits to represent, and equals 0b10001001 in binary 138 takes 8 bits to represent, and equals 0b10001010 in binary 139 takes 8 bits to represent, and equals 0b10001011 in binary 140 takes 8 bits to represent, and equals 0b10001100 in binary 141 takes 8 bits to represent, and equals 0b10001101 in binary 142 takes 8 bits to represent, and equals 0b10001110 in binary 143 takes 8 bits to represent, and equals 0b10001111 in binary 144 takes 8 bits to represent, and equals 0b10010000 in binary 145 takes 8 bits to represent, and equals 0b10010001 in binary 146 takes 8 bits to represent, and equals 0b10010010 in binary 147 takes 8 bits to represent, and equals 0b10010011 in binary 148 takes 8 bits to represent, and equals 0b10010100 in binary 149 takes 8 bits to represent, and equals 0b10010101 in binary 150 takes 8 bits to represent, and equals 0b10010110 in binary 151 takes 8 bits to represent, and equals 0b10010111 in binary 152 takes 8 bits to represent, and equals 0b10011000 in binary 153 takes 8 bits to represent, and equals 0b10011001 in binary 154 takes 8 bits to represent, and equals 0b10011010 in binary 155 takes 8 bits to represent, and equals 0b10011011 in binary 156 takes 8 bits to represent, and equals 0b10011100 in binary 157 takes 8 bits to represent, and equals 0b10011101 in binary 158 takes 8 bits to represent, and equals 0b10011110 in binary 159 takes 8 bits to represent, and equals 0b10011111 in binary 160 takes 8 bits to represent, and equals 0b10100000 in binary 161 takes 8 bits to represent, and equals 0b10100001 in binary 162 takes 8 bits to represent, and equals 0b10100010 in binary 163 takes 8 bits to represent, and equals 0b10100011 in binary 164 takes 8 bits to represent, and equals 0b10100100 in binary 165 takes 8 bits to represent, and equals 0b10100101 in binary 166 takes 8 bits to represent, and equals 0b10100110 in binary 167 takes 8 bits to represent, and equals 0b10100111 in binary 168 takes 8 bits to represent, and equals 0b10101000 in binary 169 takes 8 bits to represent, and equals 0b10101001 in binary 170 takes 8 bits to represent, and equals 0b10101010 in binary 171 takes 8 bits to represent, and equals 0b10101011 in binary 172 takes 8 bits to represent, and equals 0b10101100 in binary 173 takes 8 bits to represent, and equals 0b10101101 in binary 174 takes 8 bits to represent, and equals 0b10101110 in binary 175 takes 8 bits to represent, and equals 0b10101111 in binary 176 takes 8 bits to represent, and equals 0b10110000 in binary 177 takes 8 bits to represent, and equals 0b10110001 in binary 178 takes 8 bits to represent, and equals 0b10110010 in binary 179 takes 8 bits to represent, and equals 0b10110011 in binary 180 takes 8 bits to represent, and equals 0b10110100 in binary 181 takes 8 bits to represent, and equals 0b10110101 in binary 182 takes 8 bits to represent, and equals 0b10110110 in binary 183 takes 8 bits to represent, and equals 0b10110111 in binary 184 takes 8 bits to represent, and equals 0b10111000 in binary 185 takes 8 bits to represent, and equals 0b10111001 in binary 186 takes 8 bits to represent, and equals 0b10111010 in binary 187 takes 8 bits to represent, and equals 0b10111011 in binary 188 takes 8 bits to represent, and equals 0b10111100 in binary 189 takes 8 bits to represent, and equals 0b10111101 in binary 190 takes 8 bits to represent, and equals 0b10111110 in binary 191 takes 8 bits to represent, and equals 0b10111111 in binary 192 takes 8 bits to represent, and equals 0b11000000 in binary 193 takes 8 bits to represent, and equals 0b11000001 in binary 194 takes 8 bits to represent, and equals 0b11000010 in binary 195 takes 8 bits to represent, and equals 0b11000011 in binary 196 takes 8 bits to represent, and equals 0b11000100 in binary 197 takes 8 bits to represent, and equals 0b11000101 in binary 198 takes 8 bits to represent, and equals 0b11000110 in binary 199 takes 8 bits to represent, and equals 0b11000111 in binary 200 takes 8 bits to represent, and equals 0b11001000 in binary 201 takes 8 bits to represent, and equals 0b11001001 in binary 202 takes 8 bits to represent, and equals 0b11001010 in binary 203 takes 8 bits to represent, and equals 0b11001011 in binary 204 takes 8 bits to represent, and equals 0b11001100 in binary 205 takes 8 bits to represent, and equals 0b11001101 in binary 206 takes 8 bits to represent, and equals 0b11001110 in binary 207 takes 8 bits to represent, and equals 0b11001111 in binary 208 takes 8 bits to represent, and equals 0b11010000 in binary 209 takes 8 bits to represent, and equals 0b11010001 in binary 210 takes 8 bits to represent, and equals 0b11010010 in binary 211 takes 8 bits to represent, and equals 0b11010011 in binary 212 takes 8 bits to represent, and equals 0b11010100 in binary 213 takes 8 bits to represent, and equals 0b11010101 in binary 214 takes 8 bits to represent, and equals 0b11010110 in binary 215 takes 8 bits to represent, and equals 0b11010111 in binary 216 takes 8 bits to represent, and equals 0b11011000 in binary 217 takes 8 bits to represent, and equals 0b11011001 in binary 218 takes 8 bits to represent, and equals 0b11011010 in binary 219 takes 8 bits to represent, and equals 0b11011011 in binary 220 takes 8 bits to represent, and equals 0b11011100 in binary 221 takes 8 bits to represent, and equals 0b11011101 in binary 222 takes 8 bits to represent, and equals 0b11011110 in binary 223 takes 8 bits to represent, and equals 0b11011111 in binary 224 takes 8 bits to represent, and equals 0b11100000 in binary 225 takes 8 bits to represent, and equals 0b11100001 in binary 226 takes 8 bits to represent, and equals 0b11100010 in binary 227 takes 8 bits to represent, and equals 0b11100011 in binary 228 takes 8 bits to represent, and equals 0b11100100 in binary 229 takes 8 bits to represent, and equals 0b11100101 in binary 230 takes 8 bits to represent, and equals 0b11100110 in binary 231 takes 8 bits to represent, and equals 0b11100111 in binary 232 takes 8 bits to represent, and equals 0b11101000 in binary 233 takes 8 bits to represent, and equals 0b11101001 in binary 234 takes 8 bits to represent, and equals 0b11101010 in binary 235 takes 8 bits to represent, and equals 0b11101011 in binary 236 takes 8 bits to represent, and equals 0b11101100 in binary 237 takes 8 bits to represent, and equals 0b11101101 in binary 238 takes 8 bits to represent, and equals 0b11101110 in binary 239 takes 8 bits to represent, and equals 0b11101111 in binary 240 takes 8 bits to represent, and equals 0b11110000 in binary 241 takes 8 bits to represent, and equals 0b11110001 in binary 242 takes 8 bits to represent, and equals 0b11110010 in binary 243 takes 8 bits to represent, and equals 0b11110011 in binary 244 takes 8 bits to represent, and equals 0b11110100 in binary 245 takes 8 bits to represent, and equals 0b11110101 in binary 246 takes 8 bits to represent, and equals 0b11110110 in binary 247 takes 8 bits to represent, and equals 0b11110111 in binary 248 takes 8 bits to represent, and equals 0b11111000 in binary 249 takes 8 bits to represent, and equals 0b11111001 in binary 250 takes 8 bits to represent, and equals 0b11111010 in binary 251 takes 8 bits to represent, and equals 0b11111011 in binary 252 takes 8 bits to represent, and equals 0b11111100 in binary 253 takes 8 bits to represent, and equals 0b11111101 in binary 254 takes 8 bits to represent, and equals 0b11111110 in binary 255 takes 8 bits to represent, and equals 0b11111111 in binary 256 takes 9 bits to represent, and equals 0b100000000 in binaryIf you look carefully at the values in the output, you can notice some interesting bit patterns, e.g.:
1. Look at the bit patterns for the values of (2 ** n) - 1, i.e. values one less than each power of 2.
2. The same for the values halfway between any two adjacent powers of 2.
Notice any patterns or regularities?
The number columns in the output should really be right-justified, and the repeated (and hence redundant) text in between numbers in the rows should be replaced by a header line at the top, but this time, I've leaving this as an elementary exercise for the reader :)
Enjoy.
- Vasudev Ram - Online Python training and consulting Get updates (via Gumroad) on my forthcoming apps and content. Jump to posts: Python * DLang * xtopdf Subscribe to my blog by email My ActiveState Code recipesFollow me on: LinkedIn * Twitter Are you a blogger with some traffic? Get Convertkit:Email marketing for professional bloggers
3 comments:
Notice any possible error in the output?
Another observation:
In this Python program, I used the bit_length() method and the bin() function to calculate the number of bits needed for the integer, and the binary value of the int, respectively.
In some other languages, we might have to do at least the former manually, through some bit-manipulation code, and maybe the latter too via some additional code, unless the language has the equivalent of C's printf but for binary format.
TIL about the unit shannon, named after Claude Shannon, father of information theory:
https://en.wikipedia.org/wiki/Shannon_(unit)
https://en.wikipedia.org/wiki/Claude_Shannon
And check out his inventions section at the above page :)
Post a Comment