Calculator: The Least Interesting Devlog Post That Wasn't
Floating-point rounding, an ambiguous percent button, and why a four-function calculator hides more small decisions than it looks like.
A four-function calculator sounds like the least interesting thing I could possibly write a devlog post about, and on the surface it is — addition, subtraction, multiplication, division, percentage, sign flip. Nobody's impressed by a calculator. But it's exactly the kind of tool where "obviously simple" hides a surprising number of small decisions that are easy to get subtly wrong, and I think it's worth being honest about how much of building this was actually about floating-point arithmetic rather than button layout.
Floating-point math lies to you in small, specific ways
Type 0.1 plus 0.2 into a naive JavaScript calculator and you don't get 0.3 — you get 0.30000000000000004, because binary floating-point can't represent most decimal fractions exactly. That's not a bug in the language, it's a well-known property of how computers represent non-integer numbers, but it's exactly the kind of thing that makes a calculator look broken to anyone who tries basic decimal arithmetic. I had to round displayed results to a sane number of significant digits before showing them, while still keeping the full-precision value internally for any further calculation chained onto it. Rounding too early would compound small errors across a longer chain of operations; never rounding the display would make the tool look untrustworthy on the most basic possible input.
Percentage means different things depending on context
The percent button is the one piece of "simple" calculator behavior that's actually ambiguous. Is 50 + 10% supposed to mean "add 10, treated as a raw number" or "add 10% of 50," which are very different results? Physical calculators and calculator apps don't even agree with each other on this consistently, which meant I had to just pick a convention — percent operates relative to the other operand in the current expression, matching how most people actually expect a tip or discount calculation to behave — and make sure it's at least internally consistent rather than trying to guess intent contextually. A calculator that's unpredictable about one specific button is worse than one that's simple but consistent.
The expression display exists because trust matters more than speed
Showing the running expression above the result, rather than just a single evolving number, was a deliberate choice to preserve trust over raw minimalism. A calculator that only shows the current result hides exactly what you've entered so far, which is fine right up until you suspect you fat-fingered an earlier digit and have no way to check without starting over. Seeing "12 + 8 ×" laid out above the result lets you catch your own mistake before hitting equals, rather than after. It's a small amount of extra screen real estate in exchange for a tool that never asks you to just trust it blindly.
Full keyboard support wasn't optional
Anyone reaching for a browser calculator with a number pad already available is going to try typing before clicking, and a calculator that only responds to on-screen button clicks would feel broken to that entire category of user. Wiring up every operator key, Enter for equals, Escape for clear, and Backspace for delete took real, unglamorous attention to make sure none of it silently conflicted with normal browser keyboard shortcuts or scrolled the page unexpectedly on a stray keypress. It's invisible when it works and immediately noticeable when it doesn't, which is the exact profile of feature that's easy to underinvest in because getting it right earns no visible credit.
A history panel changes what "made a mistake" costs you
Keeping a running history of past calculations, not just the current one, was a small addition that changes the actual cost of a mistake. Without it, mistyping an earlier calculation and only noticing three steps later means redoing all of it from scratch. With a visible history, you can scroll back, spot exactly where things went wrong, and only redo the part that actually needs it. It's a cheap feature to build — just append each completed calculation to a list — and it quietly removes one of the more annoying failure modes of using any calculator for a multi-step task: losing your place entirely after a single typo.
Clearing the history needed its own explicit action rather than happening automatically on every new session, too. Some people use this for one-off arithmetic and don't care about history at all; others use it repeatedly across a session and want the trail to persist while they work. Defaulting to keeping history and giving an obvious Clear button serves both groups better than silently wiping it on a timer or a page reload would.
Where I stopped on purpose
I deliberately kept this a 4-function calculator rather than a scientific one with trig functions, exponents, and memory registers. Scientific calculators serve a genuinely different audience with genuinely different needs, and cramming both into one interface would have made the common case — quick, everyday arithmetic — more cluttered for the vast majority of people who'll ever open this tool. If a scientific calculator turns out to be worth building later, it deserves its own clean interface designed around that different use case, not a toggle bolted onto this one. There's a version of this project where I spent the same amount of effort on scientific functions instead of floating-point rounding and history, and I think that version would have been the wrong use of the time — a calculator that handles sine and cosine but occasionally shows 0.30000000000000004 for basic addition has its priorities backwards.
If I'm honest, this tool won't ever get a dramatic devlog update the way a game might — there's no boss fight to add to a calculator. What it might get is a slow trickle of exactly this kind of small correctness fix as edge cases surface: a rounding case I didn't think of, a keyboard shortcut that conflicts with something in a specific browser, a precision issue on an unusual input. That's a fine trajectory for a tool like this. Boring, reliable, and correct is the entire feature set a calculator is actually supposed to deliver.