JSFiddle - React, Tailwind, and code Playground
by Caleb Evans
HTML
<h1>Enter a decimal number:</h1>
<input id='decimal' autofocus />
<p>Your fraction is:<br /><span id='numerator'>0</span> over <span id='denominator'>1</span></p>
CSS
body {
text-align: center;
font-family: sans-serif;
font-size: 24pt;
}
h1 {
margin: 1em 0em;
font-weight: bold;
}
p {
margin: 1em 0em;
}
input {
font-size: 24pt;
}
JavaScript
/*
This algorithm was created by Caleb Evans (@caleb531). I have yet to find this particular algorithm elsewhere, so for the time being, I claim it as my own. :P
The following algorithm works by looping through all possible denominators until an integer numerator is found (by multiplying the original number by the denominator).
The algorithm works for all cases, including negative numbers, zero, one, and irrational numbers. The algorithm will also fail silently if the input is not a number (this includes NaN, undefined, and Infinity).
The algorithm can also account for binary rounding error, However, if this isn't an issue, the algorithm can be simplified further by replacing the 'if' condition with (numerator % 1 === 0).
*/
// Convert a decimal number to a fraction
function toFraction(num) {
// Cap the number of iterations at 50,000 for the sake of performance
for (var d=1; d<5e4; d+=1) {
// The numerator is always equal to the fraction times the denominator
numerator = num * d;
// Check if the proposed numerator is close enough to an integer
if (Math.abs(numerator) % 1 < 1e-12 || 1 - Math.abs(numerator) % 1 < 1e-12) {
// Stop when a numerator is found
return [Math.round(numerator), d];
}
}
// If number is irrational, return it as a fraction
return [num, 1];
}
// Handle input box functionality
$('#decimal').keyup(function() {
var num = parseFloat(this.value),
frac;
// Default to zero for non-numbers
if (isNaN(num)) {
num = 0;
}
frac = toFraction(num);
$('#numerator').html(frac[0]);
$('#denominator').html(frac[1]);
});