After years of building tools and reviewing code, I have found that the vast majority of mathematical operations in production software come down to five categories. You don't need a math degree. You need fluency in these five areas.
1. Percentage calculations
Percentages appear everywhere: discounts, tax, tips, progress bars, analytics dashboards, A/B test results.
// What is X% of Y?
const percentOf = (percent, total) => (percent / 100) * total;
// What percentage is X of Y?
const whatPercent = (part, total) => (part / total) * 100;
// Percentage change from A to B
const percentChange = (oldVal, newVal) =>
((newVal - oldVal) / oldVal) * 100;
The percentage change formula is the one developers get wrong most often. The denominator is the old value, not the new one. Going from 50 to 75 is a 50% increase. Going from 75 to 50 is a 33.3% decrease. The asymmetry catches people.
2. Linear interpolation
Mapping a value from one range to another. Used in animations, data visualization, color gradients, audio processing, and sensor calibration.
function lerp(value, inMin, inMax, outMin, outMax) {
return outMin + (value - inMin) * (outMax - outMin) / (inMax - inMin);
}
// Map a 0-1023 sensor reading to 0-100%
lerp(512, 0, 1023, 0, 100); // 50.05%
// Map a 0-1 progress value to a 200-800px width
lerp(0.75, 0, 1, 200, 800); // 650px
The inverse function (finding where a value falls in a range) is equally useful:
function inverseLerp(value, min, max) {
return (value - min) / (max - min);
}
// Where does 650 fall in the 200-800 range?
inverseLerp(650, 200, 800); // 0.75
3. Rounding and precision
JavaScript's floating-point arithmetic produces famously surprising results:
0.1 + 0.2 // 0.30000000000000004
The practical fix for display:
function round(value, decimals) {
return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}
round(0.1 + 0.2, 2); // 0.3
For financial calculations, never use floating point. Use integer cents:
// Wrong
const price = 19.99;
const tax = price * 0.08; // 1.5992000000000002
// Right
const priceCents = 1999;
const taxCents = Math.round(priceCents * 0.08); // 160
const totalCents = priceCents + taxCents; // 2159
const totalDollars = (totalCents / 100).toFixed(2); // "21.59"
4. Modular arithmetic
The modulo operator (%) is used for cycling through arrays, wrapping values, determining even/odd, and time calculations.
// Cycle through an array
const colors = ['red', 'green', 'blue'];
const color = colors[index % colors.length];
// Wrap a value within bounds
function wrap(value, min, max) {
const range = max - min;
return ((value - min) % range + range) % range + min;
}
// Convert seconds to hours:minutes:seconds
function formatTime(totalSeconds) {
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
return `${hours}:${String(minutes).padStart(2,'0')}:${String(seconds).padStart(2,'0')}`;
}
The double-modulo in the wrap function handles negative numbers. JavaScript's % operator returns negative results for negative dividends, which is usually not what you want.
5. Basic statistics
Mean, median, standard deviation. Used in monitoring, alerting, data analysis, and performance measurement.
const mean = arr => arr.reduce((a, b) => a + b, 0) / arr.length;
const median = arr => {
const sorted = [...arr].sort((a, b) => a - b);
const mid = Math.floor(sorted.length / 2);
return sorted.length % 2
? sorted[mid]
: (sorted[mid - 1] + sorted[mid]) / 2;
};
const stdDev = arr => {
const avg = mean(arr);
const variance = mean(arr.map(x => (x - avg) ** 2));
return Math.sqrt(variance);
};
Standard deviation tells you how spread out your data is. For monitoring, if a metric deviates more than 2 standard deviations from the mean, something unusual is happening. This is the basis of most anomaly detection systems.
Combining them
Real problems combine multiple operations. "Show a progress bar for a file upload with percentage and estimated time remaining":
function uploadProgress(bytesUploaded, totalBytes, elapsedMs) {
const percent = whatPercent(bytesUploaded, totalBytes);
const rate = bytesUploaded / elapsedMs; // bytes per ms
const remaining = (totalBytes - bytesUploaded) / rate;
return {
percent: round(percent, 1),
barWidth: lerp(percent, 0, 100, 0, 300), // 300px bar
remainingSeconds: Math.ceil(remaining / 1000)
};
}
For working through any mathematical calculation with step-by-step solutions, I keep a solver at zovo.one/free-tools/mathematics-solver. It handles everything from basic arithmetic to algebra and statistics. Fast, free, and shows the work.
I'm Michael Lip. I build free developer tools at zovo.one. 500+ tools, all private, all free.
Top comments (0)