<jupyter_start><jupyter_text>Numeral SystemsWe typically represent numbers in base-10. Speculation is that's because of the number of fingers we have. But base-20, base-60, and base-33 have all [been used in the past] (https://en.wikipedia.org/wiki/List_of_numeral_systems).The simplest possible number system is *base-1* (or a *tally* system): we just make a mark for everything we count. So if there are five scores for Player A in some game, we write down://///.Base-1 is fine if we are tallying wins in dice or *Yu-Gi-Oh!*, but what if our bank kept our account balance in a tally system? If you have a million dollars in the bank, your account balance statement would consist of one million tally marks! It would take about 200 pages to print your account statement just to show the balance, and it would be very hard to know if the bank were cheating you!The Roman numeral system is probably somewhat familiar to you. It is actually partially unary: 1, 2 and 3 are *I*, *II*, and *III*. Five is *V*, while four is "5 - 1," designated by putting the *I* before the *V*: *IV*. Then 6, 7 and 8 go back to unary: *VI*, *VII*, *VIII*. Ten is *X*, while nine is "10 - 1": *IX*.This system is awkward: The user has to remember lots of different letters, as the numbers keep going up, and the digits do not lineup well for operations like addition and multiplication. Fifty minus eight looks like:` L-VIII`Instead of:` 50 -8`  Positional systemsThings get much better when we line numbers up in positions according to some *base* factor, and have the idea of *zero* available for when some place is missing. These are called [positional systems](https://en.wikipedia.org/wiki/Positional_notation). So, in base ten, we have, on the far right, the *units* place, followed by the *tens* place, the *hundreds* place, the *thousands* place, and so on. With this system, we can use the same digits over and over again, to represent a number however big we want. So:<jupyter_code>10**20<jupyter_output><empty_output><jupyter_text>The main positional systems we use in computing are:- base 2 (binary)- base 8 (octal)- base 10 (decimal)- base 16 (hexidecimal)  BinaryHow do we count in, say, base-2? Just like in base-10, except that our numbers "roll over" to the next place every power of 2, instead of every power of 10. Let's count in base 2:| Base-10 number | Base-2 number | Power of 2 || -------------- | ------------- | ---------- || 0              |             0 |            | | 1              |             1 |  20 || 2              |            10 |  21 || 3              |            11 || 4              |           100 |  22 || 5              |           101 || 6              |           110 || 7              |           111 || 8              |          1000 |  23 || 9              |          1001 || 10             |          1010 || 11             |          1011 || 12             |          1100 || 13             |          1101 || 14             |          1110 || 15             |          1111 || 16             |         10000 |  24 || 32             |        100000 |  25 || 64             |       1000000 |  26 || 128            |      10000000 |  27 || 256            |     100000000 |  28 |Notice how the "space" on the number line captured by each additional digit gets bigger and bigger... in fact, that space increases with the power of the base. So, with a base-1 (tally) system, we need 1 million '1's to write one million, but in base-2, we only need 20 digits! The introduction of zero adds remarkable power to number representations.<jupyter_code>print("2^20:", 2 ** 20)
print("2^32:", bin(2 ** 32))
print("2^64:", bin(2 ** 64))
earth_years = 5000000000
days = earth_years * 365
hours = days * 24
minutes = hours * 60
seconds = minutes * 60
print("Earth has been around for:", seconds)
print("2^64:", 2 ** 64)<jupyter_output><empty_output><jupyter_text>**Note:** We could do *any* other base. For example, we'd count in base-3 like:0, 1, 2, 10 (31), 11, 12, 20, 21, 22, 100 (32), 101, 102, 110, 111, 120, 121, 122, 200... 1000 (33)  Octal| Base-10 number | Base-8 number | Power of 8 || -------------- | ------------- | ---------- || 0              |             0 |            | | 1              |             1 |  80 || 2              |             2 |            || 3              |             3 || 4              |             4 |            || 5              |             5 || 6              |             6 || 7              |             7 || 8              |            10 |  81 || 9              |            11 || 10             |            12 || 11             |            13 || 12             |            14 || 13             |            15 || 14             |            16 || 15             |            17 || 16             |            ?? || ...            |           ... || 64             |           100 |  82 || 512            |          1000 |  83 || 4096           |         10000 |  84 |**Quiz**: What number goes where the question marks are?a) 18  b) 19  c) 20  d) 30   Hexadecimal (Hex)| Base-10 number | Base-16 number | Power of 16 || -------------- | ------------- | ---------- || 0              |             0 |            | | 1              |             1 | 160 || 2              |             2 |            || 3              |             3 || 4              |             4 |            || 5              |             5 || 6              |             6 || 7              |             7 || 8              |             8 |            || 9              |             9 || 10             |             a || 11             |             b || 12             |             c || 13             |             d || 14             |             e || 15             |             f || 16             |            10 | 161 || ...            |           ... || 256            |           100 |  162 || 4096           |          1000 |  163 || 65536          |         10000 |  164 | Python can convert between these common bases. Let's write a small converter program:<jupyter_code>num = int(input("Type a decimal number to convert: "))
print(num, "in binary is", bin(num))
print(num, "in octal is", oct(num))
print(num, "in hex is", hex(num))
print("2^8:", 2 ** 8, hex(2 ** 8))
print("2^16:", 2 ** 16, hex(2 ** 16))
print("2^32:", 2 ** 32, hex(2 ** 32))
print("2^64:", 2 ** 64, hex(2 ** 64))<jupyter_output>2^8: 256 0x100
2^16: 65536 0x10000
2^32: 4294967296 0x100000000
2^64: 18446744073709551616 0x10000000000000000
{'fraction_non_alphanumeric': 0.12254977620003087, 'fraction_numerical': 0.08936564284611823, 'mean_word_length': 1.3991114402073306, 'pattern_counts': {'":': 1, '<': 12, '<?xml version=': 0, '>': 12, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 5, 'word_list_counts': {'cursed_substrings.json': 33, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '629942', 'license': 'Apache-2.0', 'n_tokens_mistral': 2126, 'n_tokens_neox': 1663, 'n_words': 751, 'path': 'notebooks/NumberRep.ipynb', 'repo_name': 'gcallah/IntroPython', 'size': '6479'}