{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "52fcc1c0-b9c1-4b0b-8b9d-86c3d419df6c",
   "metadata": {},
   "source": [
    "## PDSP 2025, Lecture 03, 14 August 2025"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "63ccc526-e5a9-40f0-81c0-2c9b6c17c60f",
   "metadata": {},
   "source": [
    "### Generating sequences of numbers\n",
    "- `range(n)` generates the sequence `0, 1, 2, ..., n-1`\n",
    "- Use `list(range(n))` to display as a list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "28b40d9c-b7bc-428d-9561-bd7918e2e259",
   "metadata": {},
   "outputs": [],
   "source": [
    "n = 17"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c1ec5ec0-7e4f-4418-b2de-1c34f6a0a98b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "range(0, 17)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "range(n)  # Like a list, but not quite"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "e6c324b5-e306-4735-ade0-4b262f969e24",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(n))  # Make it into a list"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7f4235fd-cfcf-447d-96b2-13cb8175628d",
   "metadata": {},
   "source": [
    "- `range(n)` translates to `range(0,n)`, implicitly starting with `0`\n",
    "- Can add an explicit starting point: `range(i,n)` generates `i,i+1,...,n-1`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "e1eb5b0d-2f91-43a9-95fb-b4418792e862",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(2,n))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "558267fe-5c21-4096-816a-129d85c9d85c",
   "metadata": {},
   "source": [
    "- If the starting point is $\\ge$ the target, `range` generates an empty sequence"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "88485a73-9765-4583-886b-48eb903d5e61",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(3,3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "ebfc28cc-27d8-4ab6-96f8-714b6cc68451",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[]"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(7,4))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "765db988-1dad-4d92-b519-6e2c3a8c2cb3",
   "metadata": {},
   "source": [
    "### Numbers in Python\n",
    "- Numbers in Python can be integers (`int`) or reals -- actually rationals -- (`float`)\n",
    "- Internal representation is different, but arithmetic operation symbols are *overloaded* to apply to both types of numbers\n",
    "- `+`, `-`, `*` stand for addition, subtraction, multiplication, as usual\n",
    "- `/` is division, and always produces a `float`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "e63441a0-f1fb-48ff-8b91-eb1e9a8a5dcb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.0"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "8/4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5b91203c-9283-4f9a-a60d-501de019ca16",
   "metadata": {},
   "source": [
    "- There are separate operators for *quotient* (`//`) and *remainder* (`%`)\n",
    "    - These can also be applied to `float` arguments, but the answer is also  `float`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "3e1a2522-5741-42ac-987e-4f5c7b74a364",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "8//4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f96040af-788b-4e7a-adc2-a806fbfbb33b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "7 % 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "f63afc3c-531c-4299-b193-34bc1d4b966e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2.0, 3.0)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "8.0//3.0, 8.0 % 5.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "17a38c5a-fe3d-481c-8b14-0e983fc574f4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3.0, 0.15000000000000124)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "9.3//3.05, 9.3 % 3.05"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f82b2e70-0861-45ee-a57b-7f0e7710061e",
   "metadata": {},
   "source": [
    "### Data types\n",
    "- A data type is a set of values with associated operations\n",
    "- Python has two numeric data types, `int` and `float`\n",
    "- In the IPL example, we saw text data, which is of type `String` -- we shall examine this later\n",
    "- The boolean data type has two values `True` and `False`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e31db2b-2f1f-407c-89c5-8cf0d1628db5",
   "metadata": {},
   "source": [
    "### Checking if a number is prime\n",
    "- Checking if `n` is a prime: assume it is, and flag that is not if we find a factor between `2` and `n-1`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "53c19aff-13f6-4815-9fb6-850bf78196c5",
   "metadata": {},
   "outputs": [],
   "source": [
    "n = 17\n",
    "isprime = True\n",
    "for i in range(2,n):\n",
    "    if n % i == 0:\n",
    "        isprime = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "5f60087c-1b58-4684-b766-1c1d15443760",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(17, True)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n, isprime"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "34dc01de-fa9d-40e5-984c-7910723cebd4",
   "metadata": {},
   "outputs": [],
   "source": [
    "n = 18\n",
    "isprime = True\n",
    "for i in range(2,n):\n",
    "    if n % i == 0:\n",
    "        isprime = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "64951be9-b394-46f7-8cf0-971ae91873f5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(18, False)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n, isprime"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27ca1643-04dc-4095-9874-9d2e15590799",
   "metadata": {},
   "source": [
    "### Optimising the search for factors\n",
    "- Factors occur in pairs, sufficient to check from $2$ to $\\sqrt{n}$\n",
    "- Python has a function `sqrt` to compute square roots\n",
    "- However it is not automatically available"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "c0186a4a-3222-4efa-aae0-ee27aa05653a",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'sqrt' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mNameError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[16]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43msqrt\u001b[49m(n)\n",
      "\u001b[31mNameError\u001b[39m: name 'sqrt' is not defined"
     ]
    }
   ],
   "source": [
    "sqrt(n)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2d200330-4af5-4fe1-b9d2-92f8f64ecc1e",
   "metadata": {},
   "source": [
    "### Libraries\n",
    "- Libraries are collections of code implementing different groups of functions relevant to a given theme\n",
    "- We will later see libraries specific to data science, machine learning\n",
    "- The `math` library has mathematical functions like `sqrt`, `log`, `sin`, `cos` etc\n",
    "- We `import` the `math` library to use it\n",
    "    - Note that we use `math.sqrt` to tell Python the full context of the function `sqrt`\n",
    "    - This is useful in case two different libraries have different functions with the same name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "fb476c24-9826-4b02-b7a5-5a041cd848d2",
   "metadata": {},
   "outputs": [],
   "source": [
    "import math"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "75a572c6-0cd5-4845-b094-0807623574af",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4.123105625617661"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n = 17\n",
    "math.sqrt(n)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "59074a8d-7148-4f67-996c-fee9a6e03010",
   "metadata": {},
   "source": [
    "### Optimised primality checking\n",
    "- We can optimize our search for factors by restricting the range to `(2,math.sqrt(n))`\n",
    "- `range` expects only `int` arguments, so use `int()` to convert `math.sqrt(n)` to an `int` -- truncates the fractional part"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "d15308bf-556a-4dfc-a248-6ef85539dbdd",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'float' object cannot be interpreted as an integer",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mTypeError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[19]\u001b[39m\u001b[32m, line 3\u001b[39m\n\u001b[32m      1\u001b[39m n = \u001b[32m17\u001b[39m\n\u001b[32m      2\u001b[39m isprime = \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m3\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28;43mrange\u001b[39;49m\u001b[43m(\u001b[49m\u001b[32;43m2\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43mmath\u001b[49m\u001b[43m.\u001b[49m\u001b[43msqrt\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m: \n\u001b[32m      4\u001b[39m     \u001b[38;5;28;01mif\u001b[39;00m n % i == \u001b[32m0\u001b[39m:\n\u001b[32m      5\u001b[39m         isprime = \u001b[38;5;28;01mFalse\u001b[39;00m\n",
      "\u001b[31mTypeError\u001b[39m: 'float' object cannot be interpreted as an integer"
     ]
    }
   ],
   "source": [
    "n = 17\n",
    "isprime = True\n",
    "for i in range(2,math.sqrt(n)): \n",
    "    if n % i == 0:\n",
    "        isprime = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "43e8e587-56b0-4ca1-8811-add29d932fea",
   "metadata": {},
   "outputs": [],
   "source": [
    "n = 17\n",
    "isprime = True\n",
    "for i in range(2,int(math.sqrt(n))):  # int(...) truncates a float to an int\n",
    "    if n % i == 0:\n",
    "        isprime = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "ee24fe90-08fb-4a21-b9c1-e428623017cc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "isprime"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27166fee-742e-471d-a5ee-3444f696903e",
   "metadata": {},
   "source": [
    "- We have to be careful, because `range(j,m)` stops at `m-1`\n",
    "- The code above wrongly claims `25` is a prime -- the search for factors runs from `2` to `4` rather than `2` to `5`\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "cac44a6a-5029-41b5-9d80-be768192f4ed",
   "metadata": {},
   "outputs": [],
   "source": [
    "n = 25\n",
    "isprime = True\n",
    "for i in range(2,int(math.sqrt(n))):  # int(...) truncates a float to an int\n",
    "    if n % i == 0:\n",
    "        isprime = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "88d2edfd-5dbd-4a22-938a-ad2a13587fb6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "isprime"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8f3fe955-0793-4796-947f-8d617f7a73d3",
   "metadata": {},
   "source": [
    "- To fix this, modify the upper bound of `range` to `sqrt(n)+1`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "6554115f-174c-4f14-a7de-f54585d9591c",
   "metadata": {},
   "outputs": [],
   "source": [
    "n = 25\n",
    "isprime = True\n",
    "for i in range(2,int(math.sqrt(n))+1):  # int(...) truncates a float to an int\n",
    "    if n % i == 0:\n",
    "        isprime = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "f2fa791c-a4eb-4a93-a561-a094a8d2d748",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "isprime"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "017694d3-c414-4729-86f8-8575df3c24c3",
   "metadata": {},
   "source": [
    "### Large and small numbers\n",
    "- Python allows us to work with very large (and very small numbers)\n",
    "- The operatoer `**` is exponentiation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "f5145544-44de-496b-b9ed-71a3fc843cf5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(343, 4096)"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "7**3, 2**12"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b93bc50e-08b8-4983-b74a-04dedfeb3214",
   "metadata": {},
   "source": [
    "- What is $2^{2^{12}}$, in other words, $2^{4096}$?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "23fba15d-fa6a-4562-8c90-62909ed21dbf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1044388881413152506691752710716624382579964249047383780384233483283953907971557456848826811934997558340890106714439262837987573438185793607263236087851365277945956976543709998340361590134383718314428070011855946226376318839397712745672334684344586617496807908705803704071284048740118609114467977783598029006686938976881787785946905630190260940599579453432823469303026696443059025015972399867714215541693835559885291486318237914434496734087811872639496475100189041349008417061675093668333850551032972088269550769983616369411933015213796825837188091833656751221318492846368125550225998300412344784862595674492194617023806505913245610825731835380087608622102834270197698202313169017678006675195485079921636419370285375124784014907159135459982790513399611551794271106831134090584272884279791554849782954323534517065223269061394905987693002122963395687782878948440616007412945674919823050571642377154816321380631045902916136926708342856440730447899971901781465763473223850267253059899795996090799469201774624817718449867455659250178329070473119433165550807568221846571746373296884912819520317457002440926616910874148385078411929804522981857338977648103126085903001302413467189726673216491511131602920781738033436090243804708340403154190336"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2**(2**12)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "3e3cce40-456c-41a3-9dae-4763d6b0a0c6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "16777216"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2**24"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "6c88573f-8de8-4ba5-a2b1-35ba562604ef",
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "Exceeds the limit (4300 digits) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mValueError\u001b[39m                                Traceback (most recent call last)",
      "\u001b[36mFile \u001b[39m\u001b[32m~/python-venv/lib/python3.13/site-packages/IPython/core/formatters.py:770\u001b[39m, in \u001b[36mPlainTextFormatter.__call__\u001b[39m\u001b[34m(self, obj)\u001b[39m\n\u001b[32m    763\u001b[39m stream = StringIO()\n\u001b[32m    764\u001b[39m printer = pretty.RepresentationPrinter(stream, \u001b[38;5;28mself\u001b[39m.verbose,\n\u001b[32m    765\u001b[39m     \u001b[38;5;28mself\u001b[39m.max_width, \u001b[38;5;28mself\u001b[39m.newline,\n\u001b[32m    766\u001b[39m     max_seq_length=\u001b[38;5;28mself\u001b[39m.max_seq_length,\n\u001b[32m    767\u001b[39m     singleton_pprinters=\u001b[38;5;28mself\u001b[39m.singleton_printers,\n\u001b[32m    768\u001b[39m     type_pprinters=\u001b[38;5;28mself\u001b[39m.type_printers,\n\u001b[32m    769\u001b[39m     deferred_pprinters=\u001b[38;5;28mself\u001b[39m.deferred_printers)\n\u001b[32m--> \u001b[39m\u001b[32m770\u001b[39m \u001b[43mprinter\u001b[49m\u001b[43m.\u001b[49m\u001b[43mpretty\u001b[49m\u001b[43m(\u001b[49m\u001b[43mobj\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    771\u001b[39m printer.flush()\n\u001b[32m    772\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m stream.getvalue()\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/python-venv/lib/python3.13/site-packages/IPython/lib/pretty.py:386\u001b[39m, in \u001b[36mRepresentationPrinter.pretty\u001b[39m\u001b[34m(self, obj)\u001b[39m\n\u001b[32m    383\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m \u001b[38;5;28mcls\u001b[39m \u001b[38;5;129;01min\u001b[39;00m _get_mro(obj_class):\n\u001b[32m    384\u001b[39m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mcls\u001b[39m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m.type_pprinters:\n\u001b[32m    385\u001b[39m         \u001b[38;5;66;03m# printer registered in self.type_pprinters\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m386\u001b[39m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtype_pprinters\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m(\u001b[49m\u001b[43mobj\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcycle\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    387\u001b[39m     \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m    388\u001b[39m         \u001b[38;5;66;03m# deferred printer\u001b[39;00m\n\u001b[32m    389\u001b[39m         printer = \u001b[38;5;28mself\u001b[39m._in_deferred_types(\u001b[38;5;28mcls\u001b[39m)\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/python-venv/lib/python3.13/site-packages/IPython/lib/pretty.py:786\u001b[39m, in \u001b[36m_repr_pprint\u001b[39m\u001b[34m(obj, p, cycle)\u001b[39m\n\u001b[32m    784\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"A pprint that just redirects to the normal repr function.\"\"\"\u001b[39;00m\n\u001b[32m    785\u001b[39m \u001b[38;5;66;03m# Find newlines and replace them with p.break_()\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m786\u001b[39m output = \u001b[38;5;28;43mrepr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mobj\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    787\u001b[39m lines = output.splitlines()\n\u001b[32m    788\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m p.group():\n",
      "\u001b[31mValueError\u001b[39m: Exceeds the limit (4300 digits) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit"
     ]
    }
   ],
   "source": [
    "2**(2**24)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "63d72e16-5ffd-4904-9840-c37bf7d9508d",
   "metadata": {},
   "source": [
    "- How about $2^{-4096}$?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "ba79c8dc-fb95-42e7-80c9-4cca2e1716c1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2**(-(2**12))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1cc9d78b-19c4-4824-a998-ba48d481cc35",
   "metadata": {},
   "source": [
    "- The value has become too small to distinguish from zero\n",
    "- On the other hand $2^{-1024}$ works"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "cf782cdc-a20f-4f48-b51d-921b7b67cc1d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.562684646268003e-309"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2**(-(2**10))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
