Skip to content

Instantly share code, notes, and snippets.

@joshcarter
Created October 1, 2024 02:01
Show Gist options
  • Save joshcarter/6cab54efec6ec692ac7cb5be29d0328c to your computer and use it in GitHub Desktop.
Save joshcarter/6cab54efec6ec692ac7cb5be29d0328c to your computer and use it in GitHub Desktop.
Daily Compounding Interest and Float Error Comparisor
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "86d879f6-84d2-4aea-bf20-b87b9e17dd82",
"metadata": {},
"source": [
"# Compounding Interest / Float Innacuracy"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "e00b48b2-8f38-4a1d-a9ad-089ccda26816",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# this is the way the assignment is expected to be written\n",
"# (and what the homework grader is expecting)\n",
"def daily_compounding1(years: int, rate: float, contrib: int) -> float:\n",
" balance: float = 0.0\n",
"\n",
" for y in range(years):\n",
" for month in range(12):\n",
" balance += contrib\n",
" for day in range(30):\n",
" balance = balance * (1 + rate)\n",
" \n",
" return balance"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "d0ab724f-79d4-4ad4-a1f5-88581436bd29",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# this is the way you and I wrote it (difference in last line)\n",
"def daily_compounding2(years: int, rate: float, contrib: int) -> float:\n",
" balance: float = 0.0\n",
"\n",
" for y in range(years):\n",
" for month in range(12):\n",
" balance += contrib\n",
" for day in range(30):\n",
" balance += balance * rate\n",
" \n",
" return balance"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "078e38a1-24b8-404d-96e5-20c6996893e5",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from decimal import *\n",
"\n",
"# this uses the Decimal library to get accurate results, not using floats\n",
"def daily_compounding3(years: int, rate: float, contrib: int) -> Decimal:\n",
" rate = Decimal(rate)\n",
" balance = Decimal(0.0)\n",
" \n",
"\n",
" for y in range(years):\n",
" for month in range(12):\n",
" balance += contrib\n",
" for day in range(30):\n",
" balance += balance * rate\n",
" \n",
" return balance"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "565eab45-fd14-4217-a5c7-f63e06fbe27d",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"'506012384946505732.41'"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"years = 5\n",
"rate = 0.02\n",
"contrib = 75\n",
"\n",
"answer1 = daily_compounding1(years, rate, contrib)\n",
"answer2 = daily_compounding2(years, rate, contrib)\n",
"correct = daily_compounding3(years, rate, contrib)\n",
"\n",
"# This is the correct answer with no floating-point error\n",
"\"{:0.2f}\".format(correct)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "4b47b3ff-b5bd-4b15-807c-1acf7de6e32e",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"'506012384946522688.00'"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# This is the answer the homework grader is looking for\n",
"\"{:0.2f}\".format(answer1)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "e51cd250-dceb-4138-a642-dc0f83b6a6c0",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"'506012384946505728.00'"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# This is what you originally came up with\n",
"\"{:0.2f}\".format(answer2)"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "489ce4e4-4423-4cf2-89de-93e1de9d72bf",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"'-16955.59'"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# This is how far off the homework grader's answer is, which is a fair bit\n",
"# because multiplying the balance by 1.02 compounds floating point error\n",
"# more than multiplying smaller numbers\n",
"\"{:0.2f}\".format(correct - Decimal(answer1))"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "f370a712-92f7-47b9-9196-a079c2acb75a",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"'4.41'"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# This is how far off your original answer was, which is a lot closer because\n",
"# doing multiplication of a small number and then adding that to the balance\n",
"# keeps the error under control better\n",
"\"{:0.2f}\".format(correct - Decimal(answer2))"
]
}
],
"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.11.1"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment