Decimals to fractions

<!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.