How the India in-hand salary calculator is verified
Inputs
| Input | Field | Type |
|---|---|---|
| Annual CTC (INR) | ctcAnnual | number |
| Basic as fraction of CTC (e.g. 0.40) | basicPct | number |
The formula
Each derived value below is computed by the Valem engine from the expression shown, in this order. Nothing else runs — there is no hidden code path.
| Derived value | Field | Formula (JSONata) |
|---|---|---|
| Basic | basic | $round(ctcAnnual * basicPct, 2) |
| Employee PF (12% of basic) | employeePF | $round(basic * $const.pfRate, 2) |
| Taxable income | taxable | ($t := ctcAnnual - $const.standardDeduction; $round($t > 0 ? $t : 0, 2)) |
| Slab Tax | slabTax | ($x := taxable; $t := ($x > 400000 ? (($x < 800000 ? $x : 800000) - 400000) : 0) * 0.05 + ($x > 800000 ? (($x < 1200000 ? $x : 1200000) - 800000) : 0) * 0.10 + ($x > 1200000 ? (($x < 1600000 ? $x : 1600000) - 1200000) : 0) * 0.15 + ($x > 1600000 ? (($x < 2000000 ? $x : 2000000) - 1600000) : 0) * 0.20 + ($x > 2000000 ? (($x < 2400000 ? $x : 2400000) - 2000000) : 0) * 0.25 + ($x > 2400000 ? ($x - 2400000) : 0) * 0.30; $round($t, 2)) |
| Tax After Rebate | taxAfterRebate | ($x := taxable; $r := $x <= $const.rebateTaxableLimit ? 0 : ($x - $const.rebateTaxableLimit); $t := $x <= $const.rebateTaxableLimit ? 0 : (slabTax < $r ? slabTax : $r); $round($t, 2)) |
| Tax / year | totalTax | $round(taxAfterRebate * (1 + $const.cessRate), 2) |
| In-hand / year | inHandAnnual | $round(ctcAnnual - employeePF - totalTax, 2) |
| In-hand / month | inHandMonthly | $round(inHandAnnual / 12, 2) |
Rates and thresholds
The expressions above read these as $const. They are the figures the annual refresh replaces, so they live as data rather than being written into the formulas — which is what makes a year-on-year change a one-line diff instead of an edit to arithmetic.
| Constant | Value |
|---|---|
pfRate | 0.12 |
standardDeduction | 75000 |
rebateTaxableLimit | 1200000 |
cessRate | 0.04 |
Test vectors (2)
Every case is executed against this model on each build, by the Java engine and independently by a JavaScript one. A mismatch of a single cent fails the build, so the page cannot ship advertising a figure the model no longer produces.
Case 1 — S1 CTC 8L, basic 40% — §87A rebate zeroes tax
given ctcAnnual | 800000 |
|---|---|
given basicPct | 0.4 |
expect employeePF | 38400 |
expect taxable | 725000 |
expect totalTax | 0 |
expect inHandMonthly | 63466.67 |
Case 2 — S2 CTC 18L, basic 40% — above the rebate ceiling
given ctcAnnual | 1800000 |
|---|---|
given basicPct | 0.4 |
expect taxable | 1725000 |
expect slabTax | 145000 |
Sources
- Income Tax Department — tax calculator · checked 2026-08-02
- EPFO — provident fund · checked 2026-08-02
Check it yourself — and reuse it
The whole model as JSON — inputs, outputs, formulas, vectors and sources in one re-runnable document.
This model is published under CC BY 4.0: use it, adapt it, build on it, with attribution. The licence covers the model — the expression of each rule and the arrangement of the catalog. The rates and thresholds are law, and nobody licenses those; the sources above are where they come from.
← Back to the India in-hand salary calculator
Built with Valem — a live, verifiable calculator you can fork and embed.