Skip to content

Compound Interest Calculator — C source

Project investment growth with any compounding frequency, scheduled contributions and inflation adjustment. Yearly breakdown, growth curve and CSV export — runs entirely in your browser.

This is the C implementation — the same logic the interactive tool runs, in a shareable, citable form.

/*
 * compound-interest-calculator — compound growth projection.
 *
 * Language: C (C11, standard library only)
 * Source:   CosmoDev polyglot showcase port of the Compound Interest
 *           Calculator tool, ported from src/lib/interest.ts (the canonical
 *           TypeScript implementation).
 * Tool:     https://dev.cosmolabs.org/tools/compound-interest-calculator
 * License:  display source — part of CosmoDev's polyglot tool pages.
 *
 * Display snippet: ports the core project() math from the TypeScript lib.
 * The full projection (contributions, inflation, per-year rows) lives in
 * the TypeScript/Go sources.
 *
 * Semantics: monthly simulation with the monthly rate set to the exact
 * equivalent of the stated compounding frequency — (1 + r/n)^(n/12) - 1 —
 * so the effective annual rate is preserved for every supported frequency.
 * C has no Option type, so project() writes the final balance through an
 * out-parameter and returns false on invalid input (negative principal,
 * negative years, unsupported frequency, non-finite values).
 */

#include <assert.h>
#include <math.h>
#include <stdio.h>

/* Round to 2 decimals, half-up (mirrors the TS Math.round). */
static double round2(double n)
{
    return floor(n * 100.0 + 0.5) / 100.0;
}

static int frequency_ok(unsigned compounds_per_year)
{
    switch (compounds_per_year) {
    case 1:
    case 2:
    case 4:
    case 12:
    case 365:
        return 1;
    default:
        return 0;
    }
}

/* Returns 1 and writes *out on success, 0 on invalid input. */
static int project(double principal, double rate_pct, long years,
                   unsigned compounds_per_year, double *out)
{
    if (!isfinite(principal) || !isfinite(rate_pct))
        return 0;
    if (principal < 0.0 || years < 0)
        return 0;
    if (!frequency_ok(compounds_per_year))
        return 0;

    double n = (double)compounds_per_year;
    double monthly_rate = pow(1.0 + rate_pct / 100.0 / n, n / 12.0) - 1.0;

    double balance = principal;
    for (long i = 0; i < years * 12; i++) {
        balance *= 1.0 + monthly_rate;
    }
    *out = round2(balance);
    return 1;
}

int main(void)
{
    double out = 0.0;

    /* Example:
     *   project(10000, 5, 10, 12) -> 16470.09 */
    assert(project(10000.0, 5.0, 10, 12, &out));
    assert(out == 16470.09);

    /* Invalid inputs are rejected, never clamped. */
    assert(!project(-1.0, 5.0, 10, 12, &out));   /* negative principal */
    assert(!project(10000.0, 5.0, -1, 12, &out)); /* negative years    */
    assert(!project(10000.0, 5.0, 10, 6, &out));  /* unsupported freq  */
    assert(!project(INFINITY, 5.0, 10, 12, &out)); /* non-finite value */

    printf("ok\n");
    return 0;
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →