Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Number Base Converter — By Aditya Dwi Nugraha</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| </head> | |
| <body class="bg-gray-100 text-gray-800 font-sans p-8"> | |
| <div class="container mx-auto max-w-2xl bg-white rounded-lg shadow-lg p-8"> | |
| <h1 class="text-3xl font-bold mb-6 text-center text-gray-700">Number Base Converter</h1> | |
| <div class="mb-4"> | |
| <label for="numbersInput" class="block text-sm font-medium text-gray-600 mb-2">Enter numbers (comma-separated, e.g., 1A,FF,255):</label> | |
| <input type="text" id="numbersInput" class="w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500"> | |
| </div> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> | |
| <div> | |
| <label for="baseFromInput" class="block text-sm font-medium text-gray-600 mb-2">Convert from Base (2-36):</label> | |
| <input type="number" id="baseFromInput" class="w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500" min="2" max="36" value="10"> | |
| </div> | |
| <div> | |
| <label for="baseToInput" class="block text-sm font-medium text-gray-600 mb-2">Convert to Base (2-36):</label> | |
| <input type="number" id="baseToInput" class="w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500" min="2" max="36" value="2"> | |
| </div> | |
| </div> | |
| <div class="text-center mb-6"> | |
| <button id="convertBtn" class="bg-indigo-600 text-white font-bold py-2 px-6 rounded-lg hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition duration-150 ease-in-out"> | |
| Convert | |
| </button> | |
| </div> | |
| <div id="result" class="bg-gray-50 p-4 rounded-lg border border-gray-200"> | |
| <h2 class="text-xl font-semibold mb-4 text-gray-700">Result:</h2> | |
| <pre id="output" class="whitespace-pre-wrap text-sm text-gray-800"></pre> | |
| </div> | |
| </div> | |
| <footer class="text-center mt-8"> | |
| <p class="text-gray-500 text-sm">Copyright (c) 2025 Nyxel — Aditya Dwi Nugraha. All rights reserved.</p> | |
| </footer> | |
| <script> | |
| document.getElementById('convertBtn').addEventListener('click', () => { | |
| const numbersInput = document.getElementById('numbersInput').value; | |
| const baseFromInput = document.getElementById('baseFromInput').value; | |
| const baseToInput = document.getElementById('baseToInput').value; | |
| const outputElement = document.getElementById('output'); | |
| outputElement.textContent = ''; | |
| const numberStringArray = numbersInput.split(",").map(n => n.trim().toUpperCase()); | |
| const baseFrom = Number(baseFromInput) || 10; | |
| const baseTo = Number(baseToInput) || 10; | |
| if (baseFrom < 2 || baseTo < 2 || baseFrom > 36 || baseTo > 36) { | |
| outputElement.textContent = "Error: Base must be between 2 and 36!"; | |
| return; | |
| } | |
| let responseText = ""; | |
| if (baseFrom === baseTo) { | |
| responseText += `Source Base and Target Base are the same (${baseFrom}). No conversion needed.\n`; | |
| responseText += "=====================================\n\n"; | |
| for (const numStr of numberStringArray) { | |
| const testNum = parseInt(numStr, baseFrom); | |
| if (isNaN(testNum) || testNum.toString(baseFrom).toUpperCase() !== numStr) { | |
| responseText += `Input "${numStr}" is not valid for base ${baseFrom}.\n`; | |
| } else { | |
| responseText += `Result for "${numStr}": ${numStr}\n`; | |
| } | |
| responseText += '=====================================\n\n'; | |
| } | |
| } else { | |
| for (const numStr of numberStringArray) { | |
| if (baseFrom <= 10 && /[A-Z]/i.test(numStr)) { | |
| responseText += `Input "${numStr}" is invalid because it contains letters for base ${baseFrom}.\n`; | |
| responseText += '=====================================\n\n'; | |
| continue; | |
| } | |
| const decimalNumber = parseInt(numStr, baseFrom); | |
| if (isNaN(decimalNumber)) { | |
| responseText += `Input "${numStr}" is not valid for base ${baseFrom}\n`; | |
| responseText += '=====================================\n\n'; | |
| continue; | |
| } | |
| if (baseFrom !== 10) { | |
| responseText += `--- Converting to Decimal for Number ${numStr} (base ${baseFrom}) ---\n`; | |
| const reversedDigits = numStr.split('').reverse(); | |
| const calculations = []; | |
| for (let i = 0; i < reversedDigits.length; i++) { | |
| const digit = reversedDigits[i]; | |
| const digitValue = parseInt(digit, baseFrom); | |
| const result = digitValue * Math.pow(baseFrom, i); | |
| responseText += `(${digit} -> ${digitValue}) * ${baseFrom}^${i} = ${result}\n`; | |
| calculations.push(result); | |
| } | |
| responseText += `Decimal Result: ${calculations.join(' + ')} = ${decimalNumber}\n`; | |
| responseText += '-------------------------------------\n\n'; | |
| } | |
| responseText += `--- Converting from Decimal ${decimalNumber} to Base ${baseTo} ---\n`; | |
| const resultInBaseTo = decimalNumber.toString(baseTo).toUpperCase(); | |
| let tempNumber = decimalNumber; | |
| if (tempNumber === 0) { | |
| responseText += `0 ÷ ${baseTo} = 0 -> remainder 0\n`; | |
| } else { | |
| while (tempNumber > 0) { | |
| const remainder = tempNumber % baseTo; | |
| const quotient = Math.floor(tempNumber / baseTo); | |
| const remainderChar = remainder.toString(baseTo).toUpperCase(); | |
| responseText += `${tempNumber} ÷ ${baseTo} = ${quotient} -> remainder ${remainder} (${remainderChar})\n`; | |
| tempNumber = quotient; | |
| } | |
| } | |
| responseText += `\nFinal Result: ${resultInBaseTo}\n`; | |
| responseText += '=====================================\n\n'; | |
| } | |
| } | |
| outputElement.textContent = responseText; | |
| }); | |
| </script> | |
| </body> | |
| </html> | |