DEV Community

Cover image for How to Convert Decimals to Fractions: 3 Steps With Examples
bowen Tse
bowen Tse

Posted on Originally published at toolkitloop.blogspot.com

How to Convert Decimals to Fractions: 3 Steps With Examples

Your API returns 0.375. The design mock says "⅜". The recipe your app is scaling says 0.666 cups but the user owns measuring cups marked in quarters. Somewhere between the machine world and the human world, decimals have to become fractions — and every developer, designer, or DIYer hits this gap eventually.

The good news: the conversion is a 3-step mechanical process. No memorization, no algebra tricks. Here's the whole thing.

The method in 30 seconds

  1. Write the decimal over its place value. One decimal place → over 10. Two → over 100. Three → over 1000.
  2. Find the greatest common divisor of the top and bottom numbers.
  3. Divide both by the GCD. That's your simplified fraction.

That's it. 0.75 → 75/100 → GCD(75, 100) = 25 → 3/4. Everything below is just this pattern applied to different numbers.

Why the place-value trick works

A decimal is already a fraction in disguise. "0.75" literally means "75 hundredths" — the digits after the point tell you the denominator directly. You're not computing anything in step 1; you're just rewriting notation.

The only real math is step 3: simplification. And even that has a boringly reliable procedure — divide both numbers by 2, 3, 5, whatever divides them evenly, until nothing divides both. What survives is the GCD.

Worked examples (the ones you'll actually look up)

0.5 → 5/10 → GCD(5,10) = 5 → 1/2

0.75 → 75/100 → GCD(75,100) = 25 → 3/4

0.125 → 125/1000 → GCD(125,1000) = 125 → 1/8

0.6 → 6/10 → GCD(6,10) = 2 → 3/5

1.25 → separate the whole number: 1 + 0.25 → 25/100 → GCD(25,100) = 25 → 1 1/4

Notice the pattern: the denominator is always 10, 100, or 1000 at first, then it collapses. If you remember only one thing, remember this: count the decimal places, that's your zeros.

The one case that breaks the pattern

Repeating decimals — 0.333…, 0.1666… — never terminate, so they can't be written over a power of 10. 0.333… = 1/3, but getting there needs a different technique (multiply by 10, subtract, solve). In practice, this is exactly where you stop doing it by hand and use a tool.

A 10-second demo: the tool I built (disclosure: it's mine)

Full disclosure: I built this. It's one of 30 free utilities on ToolkitLoop, and it's 100% client-side — your numbers never leave the browser.

Type a decimal and you get the simplified fraction instantly, with each simplification step shown so you can verify the math instead of trusting a black box:

Decimal-to-fraction converter showing 0.75 converted to 3/4 with the simplification steps

It also handles the awkward cases — repeating decimals, mixed numbers like 1.25, and longer decimals where the GCD isn't obvious:

Tool FAQ showing step-by-step simplification: 0.75 = 75/100, divide both by 25 to get 3/4

Try it here: decimal to fraction converter

The cheat sheet worth bookmarking

These ten cover nearly every real-world lookup — recipes, tape measures, CSS values, grades:

Decimal Fraction
0.125 1/8
0.2 1/5
0.25 1/4
0.333… 1/3
0.375 3/8
0.5 1/2
0.625 5/8
0.666… 2/3
0.75 3/4
0.875 7/8

If you're building anything that displays measurements to humans — a recipe scaler, a dashboard, a CNC readout — keep this table one keystroke away.

Bonus: the same method in 8 lines of JavaScript

Since this is dev.to, here's the whole 3-step method as code — place value, GCD via Euclid's algorithm, simplify:

function gcd(a, b) { return b ? gcd(b, a % b) : a; }

function decimalToFraction(d) {
  const places = (d.toString().split('.')[1] || '').length;
  const denom = 10 ** places;          // step 1: place value
  const num = Math.round(d * denom);
  const g = gcd(num, denom);           // step 2: GCD
  return `${num / g}/${denom / g}`;    // step 3: simplify
}

decimalToFraction(0.75);  // "3/4"
decimalToFraction(0.125); // "1/8"
Enter fullscreen mode Exit fullscreen mode

Caveat: this handles terminating decimals only — same as the manual method. Repeating decimals and floating-point dust (looking at you, 0.1 + 0.2) need a tolerance-based approach, which is exactly why the browser tool linked above exists: it shows the steps so you're never debugging a black box.

The takeaway

Decimals come from machines. Fractions come from humans. Converting is a 3-step translation: place value, GCD, simplify. For one-off conversions, do it by hand; for real work, bookmark the tool.

What's the weirdest decimal-to-fraction conversion you've had to do in a project? I'm curious where this actually shows up outside school math — drop it in the comments.

Top comments (14)

Collapse
 
alewx profile image
alex •

i use fraction.js to avoid floating‑point surprises and force rounding to the nearest 1/8 for UI labels
have you run into edge cases with recurring decimals like 1/3?

Collapse
 
bowentse profile image
bowen Tse •

Great question — this is exactly the boundary where the snippet in the article falls over, and honestly it's the reason the tool exists. Two different failure modes, needing two different fixes:

1. Float dust. d.toString() on something like 0.1 + 0.2 gives you "0.30000000000000004", so your place-count is wrong before the math even starts. fraction.js dodges this by parsing the string representation instead of trusting the float — same advice I'd give anyone: never let the float touch the algorithm, parse the input string.

2. The 1/3 boundary. This one isn't really a math problem, it's a UX decision. Is 0.3333333333 a terminating decimal that happens to be near 1/3, or did the user mean one-third and just not know repeat notation? No algorithm can read that intent, so guessing is wrong in one direction or the other. That's why the tool refuses to guess and makes it explicit instead:

  • If you mean exactly one-third, type 0.(3) — parentheses mark the repeating part, and you get exactly 1/3 with the algebraic working shown in the steps panel.
  • If you typed a long terminating tail, the "maximum denominator" control shows the nearest practical fraction and its error, so you decide whether the snap is acceptable for your case (CNC readout: yes; ledger math: probably not).

For the tolerance approach in your own code: continued fractions with a denominator cap is the standard trick — it's what produces 22/7-style "best approximations". That's essentially what fraction.js does under the hood with its epsilon.

Rule of thumb: parse strings, not floats; make repeats explicit notation; and whenever you approximate, show the error. What were you building, out of curiosity?

Collapse
 
alewx profile image
alex •

if you need exact counts, avoid floating math entirely, store millimeters as integers or use a decimal library, string parsing just masks the underlying precision problem

Thread Thread
 
bowentse profile image
bowen Tse •

Fair point, and I agree with the distinction: if your pipeline needs exact counts (accumulated measurements, money math), integers or a decimal type are the right call — recurring cases like 1/3 and running totals are exactly where float breaks down.

This converter sits at the other end of the problem: it takes what a person typed (so the typed digits are the source of truth) and reduces it to a fraction — useful for one-off conversions and UI labels like yours. It doesn't try to be a calculation engine, and it shouldn't be trusted as one. I'll call that boundary out more clearly in the article.

Thanks for the follow-up — and quick disclosure since it's relevant: I'm the founder of ToolkitLoop (toolkitloop.com), a set of free browser-side tools that never upload anything, and this converter is one of them.

Thread Thread
 
alewx profile image
alex •

right, so the parser should keep the raw string until you know the target type, otherwise you lose precision or locale info

Thread Thread
 
bowentse profile image
bowen Tse •

Exactly right — and that's actually how this converter is built. The input never passes through a float: we take the raw string, count the decimal places, and reduce (0.125 → 125/1000 → 1/8). No binary rounding ever touches the value, which is precisely what keeps the 0.1 + 0.2 class of dust out.

Fair point on locale too — comma separators like 1,5 are exactly the kind of thing a raw-string-first parser has to decide on deliberately. Right now the tool expects a period, so I've logged that as feedback. Good catch.

Thread Thread
 
alewx profile image
alex •

watch out for overflow on huge mantissas and for scientific notation, plain splitting won't normalize "1e‑9" without extra parsing

Thread Thread
 
bowentse profile image
bowen Tse •

Both fair. Mantissa overflow is real — an unbounded raw string can drag along hundreds of digits, and past a point you're just carrying noise. A sane digit cap with an honest "too long to convert exactly" message beats pretending otherwise.

Scientific notation is the trickier one: "1e-9" is a perfectly reasonable thing to paste in, and plain splitting genuinely can't normalize it without an explicit exponent-parsing step. I've logged both as feedback for the tool — the exponent case especially, since silently mangling it would be worse than rejecting it cleanly.

Thread Thread
 
alewx profile image
alex •

makes sense, the overflow noise can really kill precision. have you found a sweet digit cap that balances performance and accuracy for typical scientific inputs?

Thread Thread
 
bowentse profile image
bowen Tse •

Good question. My rule of thumb: an IEEE double only carries 15–17 significant decimal digits, so anything beyond that in a mantissa is noise no double can represent — the cap is about honesty more than performance. In the converter I keep the raw string until I know the target type (as we discussed), and trimming there loses nothing real. Performance-wise a few dozen digits are trivial either way; it only gets interesting past a few hundred. (Disclosure: I built ToolkitLoop — free tools that run locally in your browser, nothing uploaded, no signup.)

Thread Thread
 
alewx profile image
alex •

nice, the double precision limit forces that trim, and keeping the raw string until type resolution is a clean approach, have you noticed any edge cases where extra digits matter for downstream proces

Thread Thread
 
bowentse profile image
bowen Tse •

Hi Alex — good question, and honestly: not in practice.

The converter is a one-shot display tool. Your input stays as the raw string in the field, and the fraction is just rendered output — nothing downstream consumes it, so there's no pipeline where truncated digits could silently corrupt a calculation.

If someone were copying the result into a spreadsheet or a script, then the extra-digits question becomes real. And at that point my honest advice wouldn't be "trust this converter" — it'd be "don't trust any double-based converter, keep the raw string or use a decimal library." That's the boundary I try to make explicit in the tool: it answers "what fraction is this number," not "give me a number to compute with."

(For context, this is one of the free tools I built at ToolkitLoop — everything runs client-side in the browser, no uploads, no signup.)

Thread Thread
 
alewx profile image
alex •

thanks for the clarification, that lines up with how the tool is used. have you run into any edge cases where the rounding mattered for downstream copying?

Thread Thread
 
bowentse profile image
bowen Tse •

Thanks — and honestly, no: I haven't hit a real downstream incident from this tool, because it has no downstream. The converter is display-only; it never consumes its own rounded output.

The edge case I'd actually worry about isn't in the tool — it's the round-trip. Someone copies the pretty fraction off the page (say a rounded 2 7/16, or 1/3 shown as 0.33) and pastes it back as input somewhere else: a recipe site, a spreadsheet, a CAD field. Now the rounding error compounds silently, and the tool has no way to warn them.

So my rule of thumb mirrors how I built it: carry the raw input alongside the display value. If I were adding a downstream flow to this converter, I'd output both — the human-readable fraction for display, and the original decimal as the machine value (a data- attribute, or a separate "copy exact value" button). The moment a rounded value becomes the source of truth for another computation, you've lost precision you can never get back. That's exactly the digit-cap honesty I mentioned last time, taken one step further.

Disclosure: I'm bowen, founder of ToolkitLoop — the decimal-to-fraction converter I mention is one of its free browser-based tools (everything runs in the browser, nothing uploads, no signup).