| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Advanced Binary Calculator Pro</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; |
| padding: 20px; |
| color: #333; |
| } |
| |
| .container { |
| max-width: 1200px; |
| margin: 0 auto; |
| background: rgba(255, 255, 255, 0.95); |
| border-radius: 20px; |
| box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); |
| backdrop-filter: blur(10px); |
| overflow: hidden; |
| } |
| |
| .header { |
| background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); |
| color: white; |
| padding: 30px; |
| text-align: center; |
| position: relative; |
| overflow: hidden; |
| } |
| |
| .header::before { |
| content: ''; |
| position: absolute; |
| top: 0; |
| left: -100%; |
| width: 100%; |
| height: 100%; |
| background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent); |
| animation: shine 3s infinite; |
| } |
| |
| @keyframes shine { |
| 0% { left: -100%; } |
| 100% { left: 100%; } |
| } |
| |
| .header h1 { |
| font-size: 2.5em; |
| margin-bottom: 10px; |
| text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); |
| } |
| |
| .header p { |
| font-size: 1.2em; |
| opacity: 0.9; |
| } |
| |
| .main-content { |
| display: grid; |
| grid-template-columns: 1fr 1fr; |
| gap: 30px; |
| padding: 30px; |
| } |
| |
| @media (max-width: 768px) { |
| .main-content { |
| grid-template-columns: 1fr; |
| } |
| } |
| |
| .calculator-section { |
| background: white; |
| border-radius: 15px; |
| padding: 25px; |
| box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); |
| border: 1px solid #e0e0e0; |
| } |
| |
| .section-title { |
| font-size: 1.5em; |
| margin-bottom: 20px; |
| color: #4facfe; |
| text-align: center; |
| font-weight: 600; |
| } |
| |
| .input-group { |
| margin-bottom: 20px; |
| position: relative; |
| } |
| |
| .input-group label { |
| display: block; |
| margin-bottom: 8px; |
| font-weight: 500; |
| color: #555; |
| } |
| |
| .input-group input, .input-group select { |
| width: 100%; |
| padding: 12px; |
| border: 2px solid #e0e0e0; |
| border-radius: 8px; |
| font-size: 16px; |
| transition: all 0.3s ease; |
| background: #fafafa; |
| padding-right: 40px; |
| } |
| |
| .input-group input:focus, .input-group select:focus { |
| outline: none; |
| border-color: #4facfe; |
| background: white; |
| box-shadow: 0 0 0 3px rgba(79, 172, 254, 0.1); |
| } |
| |
| .clear-input-btn { |
| position: absolute; |
| right: 8px; |
| top: 65%; |
| transform: translateY(-50%); |
| background: #ff6b6b; |
| color: white; |
| border: none; |
| width: 25px; |
| height: 25px; |
| border-radius: 50%; |
| cursor: pointer; |
| font-size: 16px; |
| font-weight: bold; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| transition: all 0.3s ease; |
| } |
| |
| .clear-input-btn:hover { |
| background: #ee5a52; |
| transform: translateY(-50%) scale(1.1); |
| } |
| |
| .button-group { |
| display: grid; |
| grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); |
| gap: 15px; |
| margin-top: 20px; |
| } |
| |
| .btn { |
| padding: 12px 20px; |
| border: none; |
| border-radius: 8px; |
| font-size: 16px; |
| font-weight: 500; |
| cursor: pointer; |
| transition: all 0.3s ease; |
| text-transform: uppercase; |
| letter-spacing: 0.5px; |
| } |
| |
| .btn-primary { |
| background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); |
| color: white; |
| } |
| |
| .btn-primary:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 5px 15px rgba(79, 172, 254, 0.4); |
| } |
| |
| .btn-secondary { |
| background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); |
| color: #555; |
| } |
| |
| .btn-secondary:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 5px 15px rgba(168, 237, 234, 0.4); |
| } |
| |
| .btn-danger { |
| background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%); |
| color: white; |
| } |
| |
| .btn-danger:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 5px 15px rgba(255, 107, 107, 0.4); |
| } |
| |
| .result-display { |
| background: #f8f9fa; |
| border: 2px solid #e0e0e0; |
| border-radius: 10px; |
| padding: 20px; |
| margin-top: 20px; |
| font-family: 'Courier New', monospace; |
| font-size: 18px; |
| line-height: 1.6; |
| min-height: 60px; |
| word-break: break-all; |
| position: relative; |
| overflow-wrap: break-word; |
| } |
| |
| .result-display.success { |
| background: #e8f5e8; |
| border-color: #4caf50; |
| color: #2e7d32; |
| } |
| |
| .result-display.error { |
| background: #ffeaea; |
| border-color: #f44336; |
| color: #c62828; |
| } |
| |
| .binary-keyboard { |
| display: grid; |
| grid-template-columns: repeat(4, 1fr); |
| gap: 10px; |
| margin-top: 20px; |
| } |
| |
| @media (max-width: 600px) { |
| .binary-keyboard { |
| grid-template-columns: repeat(3, 1fr); |
| } |
| .binary-btn { |
| padding: 10px; |
| font-size: 16px; |
| } |
| } |
| |
| .binary-btn { |
| padding: 15px; |
| border: 2px solid #e0e0e0; |
| border-radius: 8px; |
| background: white; |
| cursor: pointer; |
| font-size: 18px; |
| font-weight: bold; |
| transition: all 0.3s ease; |
| } |
| |
| .binary-btn:hover { |
| background: #4facfe; |
| color: white; |
| transform: scale(1.05); |
| } |
| |
| .binary-btn.operator { |
| background: #ff6b6b; |
| color: white; |
| } |
| |
| .binary-btn.operator:hover { |
| background: #ee5a52; |
| } |
| |
| .binary-btn.btn-danger { |
| background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%); |
| color: white; |
| } |
| |
| .binary-btn.btn-danger:hover { |
| background: linear-gradient(135deg, #ee5a52 0%, #dc3545 100%); |
| } |
| |
| .binary-btn.btn-primary { |
| background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); |
| color: white; |
| } |
| |
| .binary-btn.btn-primary:hover { |
| background: linear-gradient(135deg, #00f2fe 0%, #4facfe 100%); |
| } |
| |
| .history-section { |
| background: white; |
| border-radius: 15px; |
| padding: 25px; |
| box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); |
| border: 1px solid #e0e0e0; |
| max-height: 400px; |
| overflow-y: auto; |
| } |
| |
| .history-item { |
| padding: 15px; |
| border-bottom: 1px solid #e0e0e0; |
| transition: all 0.3s ease; |
| border-radius: 8px; |
| margin-bottom: 10px; |
| } |
| |
| .history-item:hover { |
| background: #f8f9fa; |
| transform: translateX(5px); |
| } |
| |
| .history-item:last-child { |
| border-bottom: none; |
| } |
| |
| .copy-btn { |
| background: #28a745; |
| color: white; |
| border: none; |
| padding: 5px 10px; |
| border-radius: 4px; |
| cursor: pointer; |
| font-size: 12px; |
| margin-left: 10px; |
| transition: all 0.3s ease; |
| } |
| |
| .copy-btn:hover { |
| background: #218838; |
| transform: scale(1.05); |
| } |
| |
| .tabs { |
| display: flex; |
| border-bottom: 2px solid #e0e0e0; |
| margin-bottom: 20px; |
| } |
| |
| .tab { |
| padding: 12px 20px; |
| cursor: pointer; |
| border: none; |
| background: none; |
| font-size: 16px; |
| color: #666; |
| transition: all 0.3s ease; |
| flex: 1; |
| text-align: center; |
| } |
| |
| .tab.active { |
| color: #4facfe; |
| border-bottom: 3px solid #4facfe; |
| font-weight: 600; |
| } |
| |
| .tab-content { |
| display: none; |
| } |
| |
| .tab-content.active { |
| display: block; |
| } |
| |
| .conversion-grid { |
| display: grid; |
| grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); |
| gap: 15px; |
| margin-top: 20px; |
| } |
| |
| .conversion-item { |
| background: #f8f9fa; |
| padding: 15px; |
| border-radius: 8px; |
| border: 1px solid #e0e0e0; |
| } |
| |
| .conversion-item label { |
| font-weight: 600; |
| color: #4facfe; |
| margin-bottom: 8px; |
| display: block; |
| } |
| |
| .conversion-item input { |
| width: 100%; |
| padding: 10px; |
| border: 1px solid #ddd; |
| border-radius: 6px; |
| font-family: 'Courier New', monospace; |
| font-size: 14px; |
| } |
| |
| .bitwise-operations { |
| display: grid; |
| grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); |
| gap: 10px; |
| margin-top: 20px; |
| } |
| |
| .pulse { |
| animation: pulse 2s infinite; |
| } |
| |
| @keyframes pulse { |
| 0% { transform: scale(1); } |
| 50% { transform: scale(1.05); } |
| 100% { transform: scale(1); } |
| } |
| |
| .floating-elements { |
| position: fixed; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| pointer-events: none; |
| z-index: -1; |
| } |
| |
| .floating-elements::before { |
| content: ''; |
| position: absolute; |
| width: 100px; |
| height: 100px; |
| background: rgba(79, 172, 254, 0.1); |
| border-radius: 50%; |
| animation: float 6s ease-in-out infinite; |
| top: 20%; |
| left: 10%; |
| } |
| |
| .floating-elements::after { |
| content: ''; |
| position: absolute; |
| width: 60px; |
| height: 60px; |
| background: rgba(255, 107, 107, 0.1); |
| border-radius: 50%; |
| animation: float 8s ease-in-out infinite reverse; |
| top: 60%; |
| right: 10%; |
| } |
| |
| @keyframes float { |
| 0%, 100% { transform: translateY(0px); } |
| 50% { transform: translateY(-20px); } |
| } |
| </style> |
| </head> |
| <body> |
| <div class="floating-elements"></div> |
| |
| <div class="container"> |
| <div class="header"> |
| <h1>Advanced Binary Calculator Pro</h1> |
| <p>Professional-grade binary operations and conversions</p> |
| </div> |
|
|
| <div class="main-content"> |
| <div class="calculator-section"> |
| <div class="tabs"> |
| <button class="tab active" onclick="switchTab('calculator')">Calculator</button> |
| <button class="tab" onclick="switchTab('converter')">Converter</button> |
| <button class="tab" onclick="switchTab('bitwise')">Bitwise</button> |
| </div> |
|
|
| <div id="calculator" class="tab-content active"> |
| <div class="section-title">Binary Calculator</div> |
| |
| <div class="input-group"> |
| <label for="display">Display</label> |
| <input type="text" id="display" placeholder="Enter binary numbers..."> |
| </div> |
|
|
| <div class="binary-keyboard"> |
| <button class="binary-btn" onclick="appendToDisplay('0')">0</button> |
| <button class="binary-btn" onclick="appendToDisplay('1')">1</button> |
| <button class="binary-btn" onclick="backspaceDisplay()">⌫</button> |
| <button class="binary-btn operator" onclick="appendToDisplay(' + ')">+</button> |
| |
| <button class="binary-btn operator" onclick="appendToDisplay(' - ')">-</button> |
| <button class="binary-btn operator" onclick="appendToDisplay(' * ')">×</button> |
| <button class="binary-btn operator" onclick="appendToDisplay(' / ')">÷</button> |
| <button class="binary-btn operator" onclick="appendToDisplay(' & ')">&</button> |
| |
| <button class="binary-btn operator" onclick="appendToDisplay(' | ')">|</button> |
| <button class="binary-btn operator" onclick="appendToDisplay(' ^ ')">XOR</button> |
| <button class="binary-btn operator" onclick="appendToDisplay(' << ')"><<</button> |
| <button class="binary-btn operator" onclick="appendToDisplay(' >> ')">>></button> |
| |
| <button class="binary-btn operator" onclick="appendToDisplay('~')">NOT</button> |
| <button class="binary-btn operator" onclick="appendToDisplay(' ( ')">(</button> |
| <button class="binary-btn operator" onclick="appendToDisplay(' ) ')">)</button> |
| <button class="binary-btn btn-danger" onclick="clearDisplay()">Clear</button> |
| |
| <button class="binary-btn btn-primary" onclick="calculate()" style="grid-column: span 4; margin-top: 10px;">=</button> |
| </div> |
|
|
| <div class="result-display" id="calcResult"> |
| Ready for calculations... |
| </div> |
| </div> |
|
|
| <div id="converter" class="tab-content"> |
| <div class="section-title">Number System Converter</div> |
| |
| <div class="input-group"> |
| <label for="inputValue">Enter Value</label> |
| <input type="text" id="inputValue" placeholder="Enter number..." oninput="convertNumbers()"> |
| <button class="clear-input-btn" onclick="clearInput('inputValue')" title="Clear input">×</button> |
| </div> |
|
|
| <div class="input-group"> |
| <label for="inputBase">Input Base</label> |
| <select id="inputBase" onchange="convertNumbers()"> |
| <option value="2">Binary (Base 2)</option> |
| <option value="8">Octal (Base 8)</option> |
| <option value="10" selected>Decimal (Base 10)</option> |
| <option value="16">Hexadecimal (Base 16)</option> |
| </select> |
| </div> |
|
|
| <div class="conversion-grid"> |
| <div class="conversion-item"> |
| <label>Binary</label> |
| <input type="text" id="binaryResult" readonly> |
| </div> |
| <div class="conversion-item"> |
| <label>Octal</label> |
| <input type="text" id="octalResult" readonly> |
| </div> |
| <div class="conversion-item"> |
| <label>Decimal</label> |
| <input type="text" id="decimalResult" readonly> |
| </div> |
| <div class="conversion-item"> |
| <label>Hexadecimal</label> |
| <input type="text" id="hexResult" readonly喇 |
| </div> |
| </div> |
| </div> |
|
|
| <div id="bitwise" class="tab-content"> |
| <div class="section-title">Bitwise Operations</div> |
| |
| <div class="input-group"> |
| <label for="bitwiseA">First Number (Binary)</label> |
| <input type="text" id="bitwiseA" placeholder="Enter binary number..." oninput="performBitwiseOps()"> |
| <button class="clear-input-btn" onclick="clearInput('bitwiseA')" title="Clear input">×</button> |
| </div> |
|
|
| <div class="input-group"> |
| <label for="bitwiseB">Second Number (Binary)</label> |
| <input type="text" id="bitwiseB" placeholder="Enter binary number..." oninput="performBitwiseOps()"> |
| <button class="clear-input-btn" onclick="clearInput('bitwiseB')" title="Clear input">×</button> |
| </div> |
|
|
| <div class="bitwise-operations"> |
| <button class="btn btn-secondary" onclick="setBitwiseOperation('and')">AND</button> |
| <button class="btn btn-secondary" onclick="setBitwiseOperation('or')">OR</button> |
| <button class="btn btn-secondary" onclick="setBitwiseOperation('xor')">XOR</button> |
| <button class="btn btn-secondary" onclick="setBitwiseOperation('not')">NOT A</button> |
| <button class="btn btn-secondary" onclick="setBitwiseOperation('nand')">NAND</button> |
| <button class="btn btn-secondary" onclick="setBitwiseOperation('nor')">NOR</button> |
| <button class="btn btn-secondary" onclick="setBitwiseOperation('lshift')">Left Shift</button> |
| <button class="btn btn-secondary" onclick="setBitwiseOperation('rshift')">Right Shift</button> |
| </div> |
|
|
| <div class="result-display" id="bitwiseResult"> |
| Select operation and enter binary numbers... |
| </div> |
| </div> |
| </div> |
|
|
| <div class="history-section"> |
| <div class="section-title">Calculation History</div> |
| <div class="button-group"> |
| <button class="btn btn-secondary" onclick="exportHistory()">Export</button> |
| <button class="btn btn-danger" onclick="clearHistory()">Clear All</button> |
| </div> |
| <div id="historyList"> |
| <div class="history-item"> |
| <em>No calculations yet. Start calculating to see history!</em> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| let calculationHistory = []; |
| let currentBitwiseOperation = null; |
| |
| function switchTab(tabName) { |
| document.querySelectorAll('.tab-content').forEach(content => { |
| content.classList.remove('active'); |
| }); |
| document.querySelectorAll('.tab').forEach(tab => { |
| tab.classList.remove('active'); |
| }); |
| document.getElementById(tabName).classList.add('active'); |
| event.currentTarget.classList.add('active'); |
| } |
| |
| function appendToDisplay(value) { |
| const display = document.getElementById('display'); |
| display.value += value; |
| } |
| |
| function backspaceDisplay() { |
| const display = document.getElementById('display'); |
| display.value = display.value.slice(0, -1); |
| } |
| |
| function clearInput(inputId) { |
| document.getElementById(inputId).value = ''; |
| if (inputId === 'inputValue') { |
| convertNumbers(); |
| } else if (inputId === 'bitwiseA' || inputId === 'bitwiseB') { |
| performBitwiseOps(); |
| } |
| } |
| |
| function clearDisplay() { |
| document.getElementById('display').value = ''; |
| document.getElementById('calcResult').textContent = 'Ready for calculations...'; |
| document.getElementById('calcResult').className = 'result-display'; |
| } |
| |
| function calculate() { |
| const display = document.getElementById('display'); |
| const resultDiv = document.getElementById('calcResult'); |
| |
| try { |
| const expression = display.value.trim(); |
| if (!expression) { |
| throw new Error('Empty expression'); |
| } |
| |
| const result = evaluateBinaryExpression(expression); |
| const binaryResult = result.toString(2); |
| |
| resultDiv.textContent = `Result: ${binaryResult} (Decimal: ${result})`; |
| resultDiv.className = 'result-display success'; |
| |
| addToHistory(`${expression} = ${binaryResult} (${result})`); |
| |
| } catch (error) { |
| resultDiv.textContent = `Error: ${error.message}`; |
| resultDiv.className = 'result-display error'; |
| } |
| } |
| |
| function evaluateBinaryExpression(expr) { |
| try { |
| let jsExpr = expr |
| .replace(/\s+/g, ' ') |
| .replace(/([01]+)/g, (match) => parseInt(match, 2)) |
| .replace(/÷/g, '/') |
| .replace(/×/g, '*') |
| .replace(/\^/g, '^') |
| .replace(/~/g, '~') |
| .replace(/<<|>>/g, (match) => match); |
| |
| jsExpr = jsExpr.replace(/(\d+)\s*\^\s*(\d+)/g, '($1 ^ $2)'); |
| jsExpr = jsExpr.replace(/(\d+)\s*&\s*(\d+)/g, '($1 & $2)'); |
| jsExpr = jsExpr.replace(/(\d+)\s*\|\s*(\d+)/g, '($1 | $2)'); |
| jsExpr = jsExpr.replace(/(\d+)\s*<<\s*(\d+)/g, '($1 << $2)'); |
| jsExpr = jsExpr.replace(/(\d+)\s*>>\s*(\d+)/g, '($1 >> $2)'); |
| jsExpr = jsExpr.replace(/~(\d+)/g, '(~($1) >>> 0)'); |
| |
| const result = Function('"use strict"; return (' + jsExpr + ')')(); |
| if (!Number.isInteger(result) || isNaN(result)) { |
| throw new Error('Invalid calculation result'); |
| } |
| return result; |
| } catch (error) { |
| throw new Error('Invalid expression syntax'); |
| } |
| } |
| |
| function convertNumbers() { |
| const inputValue = document.getElementById('inputValue').value.trim(); |
| const inputBase = parseInt(document.getElementById('inputBase').value); |
| |
| if (!inputValue) { |
| clearConversionResults(); |
| return; |
| } |
| |
| try { |
| const decimal = parseInt(inputValue, inputBase); |
| |
| if (isNaN(decimal)) { |
| throw new Error('Invalid number format'); |
| } |
| |
| document.getElementById('binaryResult').value = decimal.toString(2); |
| document.getElementById('octalResult').value = decimal.toString(8); |
| document.getElementById('decimalResult').value = decimal.toString(10); |
| document.getElementById('hexResult').value = decimal.toString(16).toUpperCase(); |
| |
| } catch (error) { |
| clearConversionResults(); |
| } |
| } |
| |
| function clearConversionResults() { |
| document.getElementById('binaryResult').value = ''; |
| document.getElementById('octalResult').value = ''; |
| document.getElementById('decimalResult').value = ''; |
| document.getElementById('hexResult').value = ''; |
| } |
| |
| function setBitwiseOperation(operation) { |
| currentBitwiseOperation = operation; |
| document.querySelectorAll('.bitwise-operations .btn').forEach(btn => { |
| btn.classList.remove('btn-primary'); |
| btn.classList.add('btn-secondary'); |
| }); |
| |
| event.target.classList.remove('btn-secondary'); |
| event.target.classList.add('btn-primary'); |
| |
| performBitwiseOps(); |
| } |
| |
| function performBitwiseOps() { |
| const a = document.getElementById('bitwiseA').value.trim(); |
| const b = document.getElementById('bitwiseB').value.trim(); |
| const resultDiv = document.getElementById('bitwiseResult'); |
| |
| if (!currentBitwiseOperation) { |
| resultDiv.textContent = 'Select an operation first...'; |
| return; |
| } |
| |
| if (!a || (currentBitwiseOperation !== 'not' && !b)) { |
| resultDiv.textContent = 'Enter binary numbers...'; |
| return; |
| } |
| |
| try { |
| const numA = parseInt(a, 2); |
| const numB = b ? parseInt(b, 2) : 0; |
| |
| if (isNaN(numA) || (!b && currentBitwiseOperation !== 'not') || (b && isNaN(numB))) { |
| throw new Error('Invalid binary format'); |
| } |
| |
| let result; |
| let operation; |
| |
| switch (currentBitwiseOperation) { |
| case 'and': |
| result = numA & numB; |
| operation = `${a} AND ${b}`; |
| break; |
| case 'or': |
| result = numA | numB; |
| operation = `${a} OR ${b}`; |
| break; |
| case 'xor': |
| result = numA ^ numB; |
| operation = `${a} XOR ${b}`; |
| break; |
| case 'not': |
| result = (~numA >>> 0); |
| operation = `NOT ${a}`; |
| break; |
| case 'nand': |
| result = ~(numA & numB); |
| operation = `${a} NAND ${b}`; |
| break; |
| case 'nor': |
| result = ~(numA | numB); |
| operation = `${a} NOR ${b}`; |
| break; |
| case 'lshift': |
| result = numA << numB; |
| operation = `${a} << ${b}`; |
| break; |
| case 'rshift': |
| result = numA >> numB; |
| operation = `${a} >> ${b}`; |
| break; |
| default: |
| throw new Error('Unknown operation'); |
| } |
| |
| const binaryResult = result.toString(2); |
| resultDiv.textContent = `${operation} = ${binaryResult} (Decimal: ${result})`; |
| resultDiv.className = 'result-display success'; |
| |
| addToHistory(`${operation} = ${binaryResult} (${result})`); |
| |
| } catch (error) { |
| resultDiv.textContent = `Error: ${error.message}`; |
| resultDiv.className = 'result-display error'; |
| } |
| } |
| |
| function addToHistory(calculation) { |
| calculationHistory.unshift({ |
| calculation: calculation, |
| timestamp: new Date().toLocaleString() |
| }); |
| |
| if (calculationHistory.length > 50) { |
| calculationHistory = calculationHistory.slice(0, 50); |
| } |
| |
| updateHistoryDisplay(); |
| } |
| |
| function updateHistoryDisplay() { |
| const historyList = document.getElementById('historyList'); |
| |
| if (calculationHistory.length === 0) { |
| historyList.innerHTML = '<div class="history-item"><em>No calculations yet. Start calculating to see history!</em></div>'; |
| return; |
| } |
| |
| historyList.innerHTML = calculationHistory.map(item => ` |
| <div class="history-item"> |
| <div style="font-weight: bold; color: #4facfe;">${item.calculation}</div> |
| <div style="font-size: 0.9em; color: #666; margin-top: 5px;"> |
| ${item.timestamp} |
| <button class="copy-btn" onclick="copyToClipboard('${item.calculation}')">Copy</button> |
| </div> |
| </div> |
| `).join(''); |
| } |
| |
| function copyToClipboard(text) { |
| navigator.clipboard.writeText(text).then(() => { |
| const btn = event.target; |
| const originalText = btn.textContent; |
| btn.textContent = 'Copied!'; |
| btn.style.background = '#28a745'; |
| setTimeout(() => { |
| btn.textContent = originalText; |
| btn.style.background = ''; |
| }, 1000); |
| }); |
| } |
| |
| function clearHistory() { |
| calculationHistory = []; |
| updateHistoryDisplay(); |
| } |
| |
| function exportHistory() { |
| if (calculationHistory.length === 0) { |
| alert('No history to export!'); |
| return; |
| } |
| |
| const historyText = calculationHistory.map(item => |
| `${item.timestamp}: ${item.calculation}` |
| ).join('\n'); |
| |
| const blob = new Blob([historyText], { type: 'text/plain' }); |
| const url = URL.createObjectURL(blob); |
| const a = document.createElement('a'); |
| a.href = url; |
| a.download = `binary_calculator_history_${new Date().toISOString().split('T')[0]}.txt`; |
| document.body.appendChild(a); |
| a.click(); |
| document.body.removeChild(a); |
| URL.revokeObjectURL(url); |
| } |
| |
| document.addEventListener('DOMContentLoaded', function() { |
| document.addEventListener('keydown', function(e) { |
| if (document.getElementById('calculator').classList.contains('active')) { |
| if (e.key === '0' || e.key === '1') { |
| appendToDisplay(e.key); |
| } else if (e.key === 'Enter') { |
| e.preventDefault(); |
| calculate(); |
| } else if (e.key === 'Escape') { |
| clearDisplay(); |
| } else if (e.key === 'Backspace') { |
| e.preventDefault(); |
| backspaceDisplay(); |
| } |
| } |
| }); |
| |
| document.getElementById('display').addEventListener('keydown', function(e) { |
| if (e.key === 'Backspace') { |
| return; |
| } |
| if (!/[01+\-*\/&|^~()<> ]/.test(e.key) && |
| !['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab', 'Enter', 'Escape'].includes(e.key)) { |
| e.preventDefault(); |
| } |
| }); |
| |
| document.getElementById('display').addEventListener('input', function(e) { |
| e.target.value = e.target.value.replace(/[^01+\-*\/&|^~()<> ]/g, ''); |
| }); |
| |
| document.getElementById('bitwiseA').addEventListener('input', function(e) { |
| e.target.value = e.target.value.replace(/[^01]/g, ''); |
| }); |
| |
| document.getElementById('bitwiseB').addEventListener('input', function(e) { |
| e.target.value = e.target.value.replace(/[^01]/g, ''); |
| }); |
| |
| document.getElementById('inputValue').addEventListener('input', function(e) { |
| const base = parseInt(document.getElementById('inputBase').value); |
| let regex; |
| switch (base) { |
| case 2: |
| regex = /[^01]/g; |
| break; |
| case 8: |
| regex = /[^0-7]/g; |
| break; |
| case 10: |
| regex = /[^0-9]/g; |
| break; |
| case 16: |
| regex = /[^0-9a-fA-F]/g; |
| break; |
| } |
| e.target.value = e.target.value.replace(regex, ''); |
| convertNumbers(); |
| }); |
| |
| convertNumbers(); |
| }); |
| </script> |
| </body> |
| </html> |