Loan offers, mutual fund brochures, fixed-deposit tables, shop bills and exam forms all ask the same kind of question: "what does this number actually come to?" The answers are small pieces of arithmetic, but they are easy to get subtly wrong — a monthly rate used as an annual one, a SIP treated as a lump sum, an age counted in 30-day months. We built five calculators for India that run entirely in the browser, and this post is about the maths inside them: the formulas, the edge cases, and the places where we deliberately refuse to over-claim.
Every calculator follows the same three rules. First, the maths is a pure function of its inputs — no DOM, no network, nothing uploaded. Second, money is formatted for India with Intl.NumberFormat('en-IN'), so ₹1,00,000 groups the way Indian readers expect, not as 100,000. Third, displayed rupees are rounded with Math.round (whole rupees for EMI, SIP and FD; two decimals for GST), and the page says the result is indicative — a bank's exact figure can differ by a few rupees through fees or its own rounding.
The live tools are here: Free India Calculators — EMI, SIP, FD, GST & Age.
EMI: the standard formula, plus the branch everyone forgets
The monthly instalment for a loan of principal P, monthly rate r and n months is:
var r = annualRate / 1200; // annual % -> monthly decimal var f = Math.pow(1 + r, months); emi = P * r * f / (f - 1); Dividing the annual percentage by 1200 (12 months × 100) is the step most hand-rolled versions get wrong first. The formula also has a hole: at a 0% rate it divides by zero, since f - 1 is 0. The code branches on it:
if (r === 0) { emi = P / months; } else { var f = Math.pow(1 + r, months); emi = P * r * f / (f - 1); } total = emi * months; Total interest is then total - P. Verified figure: a ₹1,00,000 loan at 10% for 1 year gives ₹8,792 per month. The page also shows the tenure trade-off plainly: a longer tenure lowers the EMI but raises total interest, because interest runs for more months.
SIP: a monthly annuity due, labelled an estimate
A SIP is not a lump sum growing for n years — it is a payment made every month, each instalment compounding for a different length of time. The future value of a monthly SIP is the annuity-due formula:
var i = annualRate / 1200; var n = Math.round(years * 12); total = monthly * ((Math.pow(1 + i, n) - 1) / i) * (1 + i); The trailing (1 + i) is the "due" part: payments are assumed at the start of each month, so every instalment — including the last — earns one extra month of growth compared with end-of-month payments. Drop it and you understate the result by roughly one month's return.
The honesty surface matters more than the formula here. The default assumed return is 12% a year, and every figure is labelled an estimate on the page itself: mutual fund returns are market-linked, never guaranteed, and a steady 12% every year is a planning assumption, not a prediction. Verified figure at that default: ₹5,000 a month for 10 years invests ₹6,00,000 and gives an estimated total of ₹11,61,695.
FD: quarterly compounding, because that is the Indian bank standard
Fixed-deposit maturity uses compound growth with a frequency parameter:
var A = P * Math.pow(1 + annualRate / (100 * freq), freq * years); Most Indian banks compound quarterly, so the default is freq = 4 — interest starts earning interest sooner than with yearly compounding, which is why the same stated rate pays slightly more. Verified figure: ₹1,00,000 at 6.5% for 5 years matures to ₹1,38,042. The page notes the tax caveat too: FD interest is taxable income, so the in-hand amount can be lower after TDS.
GST: add and remove are not the same operation
Adding GST is multiplication; removing it is division, and confusing the two is a common billing error:
// Add: base 1000, rate 18% -> tax 180, total 1180 tax = base * rate / 100; // Remove: total 1180, rate 18% -> base 1000, tax 180 base = total / (1 + rate / 100); Removing 18% from ₹1,180 by subtracting 18% of 1,180 gives ₹967.60 — wrong. Dividing by 1.18 gives the correct ₹1,000. For intra-state sales the tax is split equally into CGST and SGST; for inter-state sales the same total is charged as IGST. GST amounts keep two decimal places, unlike the whole-rupee rounding elsewhere, because paise matter on a bill. The supported slabs are 5%, 12%, 18% and 28%, plus a custom rate.
Age: calendar maths, done in UTC
"How old am I on the cut-off date?" decides exam and job eligibility, and it must be answered in completed calendar years, months and days — not by dividing a day count by 365. The algorithm subtracts year, month and day separately, borrowing when a component goes negative:
var years = o.y - b.y; var months = o.m - b.m; var days = o.d - b.d; if (days < 0) { months--; days += new Date(Date.UTC(o.y, o.m - 1, 0)).getUTCDate(); } if (months < 0) { years--; months += 12; } Borrowing "the days in the previous month" — via day 0 of the current month, which is the last day of the previous one — handles February and 30/31-day months correctly. All of this runs on Date.UTC values, so daylight-saving transitions can never shift a date by an hour and corrupt the day count; total days lived is (onUTC - dobUTC) / 86400000. The same code also yields the weekday of birth and the countdown to the next birthday.
What the calculators refuse to do
No input is uploaded or stored — there is no endpoint at all, so there is nothing to trust. No result is presented as a promise: EMI figures are indicative against the bank's own calculation, SIP figures are estimates against a market that never returns a flat rate, and FD figures are pre-tax. A calculator that quietly rounds a guess into a confident-looking rupee figure is worse than no calculator; the interesting engineering here is not the five formulas, which fit in a few lines each, but keeping each one honest about what it cannot know.



