<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Decimal to Fraction</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container {
background: white;
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
padding: 40px;
max-width: 500px;
width: 100%;
text-align: center;
}
h1 {
color: #333;
margin-bottom: 10px;
font-size: 2.5em;
font-weight: 300;
}
.subtitle {
color: #666;
margin-bottom: 30px;
font-size: 1.1em;
}
.input-group {
margin-bottom: 30px;
position: relative;
}
input[type="number"] {
width: 100%;
padding: 15px 20px;
border: 2px solid #e1e5e9;
border-radius: 50px;
font-size: 1.2em;
text-align: center;
transition: all 0.3s ease;
background: #f8f9fa;
}
input[type="number"]:focus {
outline: none;
border-color: #667eea;
background: white;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.convert-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 15px 40px;
border-radius: 50px;
font-size: 1.1em;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
margin: 10px;
min-width: 150px;
}
.convert-btn:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(102, 126, 234, 0.3);
}
.convert-btn:active {
transform: translateY(0);
}
.results {
margin-top: 30px;
padding: 25px;
background: #f8f9fa;
border-radius: 15px;
border-left: 4px solid #667eea;
}
.result-item {
margin: 15px 0;
font-size: 1.3em;
}
.fraction-display {
font-size: 2.5em;
font-weight: bold;
color: #333;
margin: 20px 0;
line-height: 1.2;
}
.numerator {
display: inline-block;
border-bottom: 3px solid #333;
padding-bottom: 5px;
margin-right: 10px;
}
.denominator {
display: inline-block;
margin-left: 10px;
}
.decimal-display {
font-size: 1.5em;
color: #667eea;
background: white;
padding: 10px 20px;
border-radius: 25px;
display: inline-block;
margin: 10px 0;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.precision-controls {
display: flex;
justify-content: center;
: 10px;
margin: 20px 0;
flex-wrap: wrap;
}
.precision-btn {
background: white;
border: 2px solid #e1e5e9;
padding: 8px 16px;
border-radius: 20px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 0.9em;
}
.precision-btn.active,
.precision-btn:hover {
border-color: #667eea;
background: #667eea;
color: white;
}
.error {
color: #e74c3c;
background: #fdf2f2;
border: 1px solid #f5c6cb;
padding: 15px;
border-radius: 10px;
margin: 20px 0;
}
.info {
background: #d4edda;
border: 1px solid #c3e6cb;
color: #155724;
padding: 15px;
border-radius: 10px;
margin: 20px 0;
font-size: 0.95em;
}
.mixed-number {
font-size: 1.8em;
color: #2c3e50;
margin: 15px 0;
}
@media (max-width: 480px) {
.container {
padding: 25px;
margin: 10px;
}
h1 {
font-size: 2em;
}
.fraction-display {
font-size: 2em;
}
.precision-controls {
flex-direction: column;
align-items: center;
}
}
</style>
</head>
<body>
<div class="container">
<h1>🔢 Decimal to Fraction</h1>
<p class="subtitle">Convert decimal numbers to simplified fractions instantly</p>
<div class="input-group">
<input type="number" id="decimalInput" step="any" placeholder="Enter a decimal number (e.g., 0.75, 3.25)" />
</div>
<button class="convert-btn" onclick="convertDecimal()">Convert to Fraction</button>
<div class="precision-controls">
<button class="precision-btn active" onclick="setPrecision('auto')">Auto</button>
<button class="precision-btn" onclick="setPrecision(2)">2 Decimals</button>
<button class="precision-btn" onclick="setPrecision(4)">4 Decimals</button>
<button class="precision-btn" onclick="setPrecision(6)">6 Decimals</button>
<button class="precision-btn" onclick="setPrecision(8)">8 Decimals</button>
</div>
<div id="results" class="results" style="display: none;">
<div id="errorMessage" class="error" style="display: none;"></div>
<div id="decimalDisplay" class="decimal-display"></div>
<div class="fraction-display" id="fractionDisplay">
<span class="numerator" id="numerator"></span>
<span>/</span>
<span class="denominator" id="denominator"></span>
</div>
<div id="mixedNumber" class="mixed-number" style="display: none;"></div>
<div class="result-item">
<strong>Simplified:</strong> <span id="simplified"></span>
</div>
<div class="result-item">
<strong>Decimal Value:</strong> <span id="decimalValue"></span>
</div>
</div>
<div class="info">
<strong>How it works:</strong> This converter uses the continued fraction algorithm to find the simplest fraction representation of any decimal number. For repeating decimals, it approximates based on the specified precision.
</div>
</div>
<script>
let currentPrecision = 'auto';
const input = document.getElementById('decimalInput');
// Allow Enter key to trigger conversion
input.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
convertDecimal();
}
});
// Auto-convert when user stops typing
let timeout;
input.addEventListener('input', function() {
clearTimeout(timeout);
timeout = setTimeout(convertDecimal, 500);
});
function setPrecision(precision) {
currentPrecision = precision;
// Update button states
document.querySelectorAll('.precision-btn').forEach(btn => {
btn.classList.remove('active');
});
event.target.classList.add('active');
// Re-convert if there's input
if (input.value) {
convertDecimal();
}
}
function showError(message) {
const errorDiv = document.getElementById('errorMessage');
errorDiv.textContent = message;
errorDiv.style.display = 'block';
document.getElementById('results').style.display = 'block';
}
function hideError() {
const errorDiv = document.getElementById('errorMessage');
errorDiv.style.display = 'none';
}
function gcd(a, b) {
while (b !== 0) {
let temp = b;
b = a % b;
a = temp;
}
return a;
}
function fractionToMixedNumber(numerator, denominator) {
if (numerator < denominator) return null;
const whole = Math.floor(numerator / denominator);
const remainder = numerator % denominator;
if (remainder === 0) {
return `${whole}`;
}
return `${whole} ${remainder}/${denominator}`;
}
function continuedFractionApproximation(x, maxTerms = 20) {
const terms = [];
let integerPart = Math.floor(x);
let fractionalPart = x - integerPart;
terms.push(integerPart);
for (let i = 0; i < maxTerms && fractionalPart > 1e-10; i++) {
integerPart = Math.floor(1 / fractionalPart);
fractionalPart = 1 / fractionalPart - integerPart;
terms.push(integerPart);
if (fractionalPart < 1e-10) break;
}
return terms;
}
function convergentsFromContinuedFraction(terms) {
let h = [0, 1];
let k = [1, 0];
for (let i = 0; i < terms.length; i++) {
const a = terms[i];
const hNew = a * h[i + 1] + h[i];
const kNew = a * k[i + 1] + k[i];
h.push(hNew);
k.push(kNew);
}
return { numerators: h, denominators: k };
}
function convertDecimal() {
const decimalStr = input.value.trim();
if (!decimalStr) {
document.getElementById('results').style.display = 'none';
return;
}
hideError();
const decimal = parseFloat(decimalStr);
if (isNaN(decimal)) {
showError('Please enter a valid decimal number.');
return;
}
if (decimal === 0) {
showResult(0, 1, decimal);
return;
}
if (Math.abs(decimal) > 1000000) {
showError('Please enter a number between -1,000,000 and 1,000,000.');
return;
}
// Handle negative numbers
const isNegative = decimal < 0;
const absDecimal = Math.abs(decimal);
let numerator, denominator;
// Check if it's a simple terminating decimal
if (currentPrecision !== 'auto') {
const precision = Math.pow(10, currentPrecision);
const scaledDecimal = Math.round(absDecimal * precision);
numerator = scaledDecimal;
denominator = precision;
} else {
// Use continued fraction for better approximation
const terms = continuedFractionApproximation(absDecimal);
const convergents = convergentsFromContinuedFraction(terms);
// Find the best convergent (closest to original decimal)
let bestIndex = convergents.numerators.length - 1;
let minError = Infinity;
for (let i = 1; i < convergents.numerators.length; i++) {
const approx = convergents.numerators[i] / convergents.denominators[i];
const error = Math.abs(approx - absDecimal);
if (error < minError && convergents.denominators[i] <= 10000) {
minError = error;
bestIndex = i;
}
}
numerator = convergents.numerators[bestIndex];
denominator = convergents.denominators[bestIndex];
}
// Simplify the fraction
const divisor = gcd(numerator, denominator);
numerator = Math.round(numerator / divisor);
denominator = Math.round(denominator / divisor);
// Apply sign
if (isNegative) {
numerator = -numerator;
}
showResult(numerator, denominator, decimal);
}
function showResult(numerator, denominator, originalDecimal) {
document.getElementById('results').style.display = 'block';
// Display decimal
document.getElementById('decimalDisplay').textContent =
`Original: ${originalDecimal.toFixed(Math.max(8, originalDecimal.toString().split('.')[1]?.length || 2))}`;
// Display fraction
document.getElementById('numerator').textContent = Math.abs(numerator);
document.getElementById('denominator').textContent = denominator;
// Handle negative sign
const fractionDisplay = document.getElementById('fractionDisplay');
if (numerator < 0) {
fractionDisplay.style.color = '#e74c3c';
document.getElementById('numerator').textContent = `-${Math.abs(numerator)}`;
} else {
fractionDisplay.style.color = '#333';
}
// Show mixed number if applicable
const mixedNumberDiv = document.getElementById('mixedNumber');
if (Math.abs(numerator) >= denominator && denominator !== 1) {
const mixed = fractionToMixedNumber(Math.abs(numerator), denominator);
if (numerator < 0) {
mixedNumberDiv.innerHTML = `<span style="color: #e74c3c;">-</span>${mixed}`;
} else {
mixedNumberDiv.textContent = mixed;
}
mixedNumberDiv.style.display = 'block';
} else {
mixedNumberDiv.style.display = 'none';
}
// Calculate decimal value of simplified fraction
const decimalValue = (numerator / denominator).toFixed(10);
document.getElementById('simplified').textContent =
`${Math.abs(numerator)}/${denominator} (simplest form)`;
document.getElementById('decimalValue').innerHTML =
`Equals: ${decimalValue} (exact)`;
}
// Initial conversion if there's a default value
if (input.value) {
convertDecimal();
}
</script>
</body>
</html>Copy the above code to a text editor like Notepad or Notepad++ and save as index.html. Open the web page.