binary to decimal

This commit is contained in:
2026-05-12 06:26:33 -04:00
parent 7db6fc0bab
commit 32c4035c23
11 changed files with 887 additions and 5 deletions

View File

@@ -0,0 +1,459 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Binary to Decimal Converter - Form 1</title>
<style>
:root {
--primary: #4527a0;
--accent: #00838f;
--soft: #ede7f6;
--soft-alt: #d1c4e9;
--good: #2e7d32;
--good-soft: #e8f5e9;
--warn: #c62828;
--warn-soft: #ffebee;
--ink: #1a1a1a;
}
* { box-sizing: border-box; }
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.5;
max-width: 1100px;
margin: 0 auto;
padding: 20px;
background: #f5f3fa;
color: var(--ink);
}
.app {
background: #fff;
padding: 28px 34px;
border: 2px solid var(--primary);
box-shadow: 0 2px 10px rgba(69, 39, 160, 0.08);
}
.header {
text-align: center;
border-bottom: 3px solid var(--primary);
padding-bottom: 12px;
margin-bottom: 18px;
}
.header h1 { margin: 0; font-size: 1.6em; color: var(--primary); }
.header h2 { margin: 4px 0 0; font-size: 1em; color: var(--accent); font-weight: normal; }
h3 {
border-bottom: 2px solid var(--primary);
padding: 6px 0;
margin: 22px 0 10px 0;
font-size: 1.1em;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--primary);
}
.input-row {
display: flex;
gap: 14px;
align-items: center;
flex-wrap: wrap;
margin-bottom: 12px;
}
.input-row label {
font-weight: bold;
color: var(--primary);
font-size: 1em;
}
#binaryInput {
font-family: 'Courier New', monospace;
font-size: 1.6em;
padding: 6px 10px;
border: 2px solid var(--primary);
color: var(--primary);
letter-spacing: 4px;
width: 220px;
text-align: center;
background: #fff;
}
#binaryInput:focus {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
button {
font-family: inherit;
font-size: 0.95em;
padding: 8px 14px;
border: 1.5px solid var(--accent);
background: #fff;
color: var(--accent);
font-weight: bold;
cursor: pointer;
text-transform: uppercase;
letter-spacing: 0.4px;
}
button:hover { background: var(--soft); color: var(--primary); border-color: var(--primary); }
button.primary { background: var(--primary); color: #fff; border-color: var(--primary); }
button.primary:hover { background: #311b92; color: #fff; }
button.warn { color: var(--warn); border-color: var(--warn); }
button.warn:hover { background: var(--warn-soft); color: var(--warn); }
.preset-row {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin: 6px 0 12px;
}
.preset-row button {
font-family: 'Courier New', monospace;
letter-spacing: 2px;
padding: 4px 10px;
font-size: 1em;
text-transform: none;
}
.chart-wrapper {
border: 2px solid var(--primary);
padding: 14px;
margin: 12px 0;
background: var(--soft);
overflow-x: auto;
}
.chart {
margin: 0 auto;
border-collapse: collapse;
font-family: 'Courier New', monospace;
}
.chart td {
border: 1.5px solid var(--primary);
padding: 10px 18px;
text-align: center;
background: #fff;
min-width: 64px;
}
.chart .row-power { background: var(--soft); color: var(--primary); font-weight: bold; font-size: 1em; }
.chart .row-value { background: #fff; color: var(--primary); font-weight: bold; font-size: 1.15em; }
.chart .row-digit { background: #fff; font-size: 1.6em; font-weight: bold; }
.chart .row-contrib { background: #fafbfc; color: var(--accent); font-weight: bold; font-size: 1.05em; }
.chart .row-digit.is-one { background: var(--good-soft); color: var(--good); }
.chart .row-contrib.is-one { background: var(--good-soft); color: var(--good); }
.chart .row-digit.is-zero { color: #888; }
.chart .row-contrib.is-zero { color: #888; }
.working-line {
text-align: center;
font-family: 'Courier New', monospace;
font-size: 1.2em;
margin: 10px 0;
color: var(--primary);
font-weight: bold;
}
.answer-banner {
border: 2px solid var(--good);
background: var(--good-soft);
color: var(--good);
padding: 14px 18px;
text-align: center;
font-size: 1.4em;
font-weight: bold;
margin: 14px 0 6px;
font-family: 'Courier New', monospace;
}
.answer-banner.hidden {
background: var(--soft);
color: var(--primary);
border-color: var(--primary);
}
.error-banner {
border: 2px solid var(--warn);
background: var(--warn-soft);
color: var(--warn);
padding: 10px 14px;
text-align: center;
font-weight: bold;
margin: 12px 0;
}
.controls-row {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin: 6px 0 0;
}
.footer-note {
margin-top: 18px;
padding: 8px 12px;
border-left: 4px solid var(--accent);
background: var(--soft);
color: var(--primary);
font-size: 0.92em;
}
@media print {
body { background: #fff !important; color: #000 !important; }
.app { border: 1.5px solid #000 !important; box-shadow: none !important; }
*, *::before, *::after {
background: #fff !important;
background-color: #fff !important;
color: #000 !important;
box-shadow: none !important;
}
.header, h3, .chart-wrapper, .chart td, .answer-banner, .error-banner, button, .footer-note {
border-color: #000 !important;
}
button { display: none !important; }
}
</style>
</head>
<body>
<div class="app">
<div class="header">
<h1>BINARY &rarr; DECIMAL CONVERTER</h1>
<h2>Form 1 - Lesson 30 - Same shape, different base</h2>
</div>
<h3>Type a Binary Number</h3>
<div class="input-row">
<label for="binaryInput">Binary:</label>
<input id="binaryInput" type="text" maxlength="8" autocomplete="off" spellcheck="false" placeholder="e.g. 1011">
<button class="primary" id="convertBtn">Convert</button>
<button id="clearBtn">Clear</button>
<button id="randomBtn">Random</button>
</div>
<div class="preset-row">
<button data-preset="101">101</button>
<button data-preset="1011">1011</button>
<button data-preset="1101">1101</button>
<button data-preset="10101">10101</button>
<button data-preset="11000">11000</button>
<button data-preset="11111">11111</button>
<button data-preset="100000">100000</button>
<button data-preset="110010">110010</button>
</div>
<div id="errorMsg" class="error-banner" style="display: none;"></div>
<h3>Place Value Chart (powers of 2)</h3>
<div class="chart-wrapper">
<table class="chart">
<tbody id="chartBody"></tbody>
</table>
</div>
<div id="workingLine" class="working-line"></div>
<div id="answerBanner" class="answer-banner hidden">Type a binary number above and press Convert.</div>
<div class="controls-row">
<button id="revealBtn">Hide Answer</button>
<button id="hideChartBtn">Hide Chart</button>
</div>
<div class="footer-note">
<strong>For students:</strong> solve on paper <em>first</em> using the chart in your worksheet. Type the binary number here only to <em>check</em>. The lesson is in the chart, not the click.
</div>
</div>
<script>
(function() {
const input = document.getElementById('binaryInput');
const convertBtn = document.getElementById('convertBtn');
const clearBtn = document.getElementById('clearBtn');
const randomBtn = document.getElementById('randomBtn');
const revealBtn = document.getElementById('revealBtn');
const hideChartBtn = document.getElementById('hideChartBtn');
const chartBody = document.getElementById('chartBody');
const chartWrapper = document.querySelector('.chart-wrapper');
const workingLine = document.getElementById('workingLine');
const answerBanner = document.getElementById('answerBanner');
const errorMsg = document.getElementById('errorMsg');
let answerHidden = false;
let chartHidden = false;
function clearError() {
errorMsg.style.display = 'none';
errorMsg.textContent = '';
}
function showError(msg) {
errorMsg.textContent = msg;
errorMsg.style.display = 'block';
}
function powerOfTwo(n) {
let v = 1;
for (let i = 0; i < n; i++) v *= 2;
return v;
}
function buildChartFor(binaryStr) {
const n = binaryStr.length;
const powerRow = document.createElement('tr');
const valueRow = document.createElement('tr');
const digitRow = document.createElement('tr');
const contribRow = document.createElement('tr');
powerRow.className = '';
for (let i = 0; i < n; i++) {
const exponent = n - 1 - i;
const digit = binaryStr[i];
const placeVal = powerOfTwo(exponent);
const contrib = parseInt(digit, 10) * placeVal;
const pTd = document.createElement('td');
pTd.className = 'row-power';
pTd.innerHTML = '2<sup>' + exponent + '</sup>';
powerRow.appendChild(pTd);
const vTd = document.createElement('td');
vTd.className = 'row-value';
vTd.textContent = placeVal;
valueRow.appendChild(vTd);
const dTd = document.createElement('td');
dTd.className = 'row-digit ' + (digit === '1' ? 'is-one' : 'is-zero');
dTd.textContent = digit;
digitRow.appendChild(dTd);
const cTd = document.createElement('td');
cTd.className = 'row-contrib ' + (digit === '1' ? 'is-one' : 'is-zero');
cTd.textContent = contrib;
contribRow.appendChild(cTd);
}
chartBody.innerHTML = '';
chartBody.appendChild(powerRow);
chartBody.appendChild(valueRow);
chartBody.appendChild(digitRow);
chartBody.appendChild(contribRow);
}
function renderEmpty() {
chartBody.innerHTML = '';
const powerRow = document.createElement('tr');
const valueRow = document.createElement('tr');
const digitRow = document.createElement('tr');
const contribRow = document.createElement('tr');
for (let exp = 5; exp >= 0; exp--) {
const placeVal = powerOfTwo(exp);
const pTd = document.createElement('td');
pTd.className = 'row-power';
pTd.innerHTML = '2<sup>' + exp + '</sup>';
powerRow.appendChild(pTd);
const vTd = document.createElement('td');
vTd.className = 'row-value';
vTd.textContent = placeVal;
valueRow.appendChild(vTd);
const dTd = document.createElement('td');
dTd.className = 'row-digit is-zero';
dTd.textContent = '_';
digitRow.appendChild(dTd);
const cTd = document.createElement('td');
cTd.className = 'row-contrib is-zero';
cTd.textContent = '_';
contribRow.appendChild(cTd);
}
chartBody.appendChild(powerRow);
chartBody.appendChild(valueRow);
chartBody.appendChild(digitRow);
chartBody.appendChild(contribRow);
workingLine.textContent = '';
setBanner('Type a binary number above and press Convert.', true);
}
function setBanner(text, hidden) {
answerBanner.textContent = text;
if (hidden) answerBanner.classList.add('hidden');
else answerBanner.classList.remove('hidden');
}
function convert() {
clearError();
const raw = input.value.trim();
if (raw.length === 0) {
showError('Type a binary number first (only 0s and 1s).');
renderEmpty();
return;
}
if (!/^[01]+$/.test(raw)) {
showError('Binary numbers use only 0 and 1. Found another digit.');
renderEmpty();
return;
}
if (raw.length > 8) {
showError('Keep it to 8 digits or fewer for this lesson.');
return;
}
buildChartFor(raw);
const n = raw.length;
let total = 0;
const ones = [];
const allTerms = [];
for (let i = 0; i < n; i++) {
const exponent = n - 1 - i;
const digit = parseInt(raw[i], 10);
const placeVal = powerOfTwo(exponent);
allTerms.push(digit + '×' + placeVal);
if (digit === 1) {
ones.push(placeVal);
total += placeVal;
}
}
const fullExpansion = allTerms.join(' + ');
const onesOnly = ones.length > 0 ? ones.join(' + ') + ' = ' + total : '0';
workingLine.innerHTML = fullExpansion + '<br>= ' + onesOnly;
if (answerHidden) {
setBanner(raw + '₂ = ? (press Show Answer)', true);
} else {
setBanner(raw + '₂ = ' + total + ' in denary', false);
}
}
input.addEventListener('input', function() {
input.value = input.value.replace(/[^01]/g, '');
});
input.addEventListener('keydown', function(e) {
if (e.key === 'Enter') convert();
});
convertBtn.addEventListener('click', convert);
clearBtn.addEventListener('click', function() {
input.value = '';
clearError();
renderEmpty();
input.focus();
});
randomBtn.addEventListener('click', function() {
const len = 3 + Math.floor(Math.random() * 4);
let s = '1';
for (let i = 1; i < len; i++) {
s += (Math.random() < 0.5 ? '0' : '1');
}
input.value = s;
convert();
});
document.querySelectorAll('.preset-row button[data-preset]').forEach(function(btn) {
btn.addEventListener('click', function() {
input.value = btn.getAttribute('data-preset');
convert();
});
});
revealBtn.addEventListener('click', function() {
answerHidden = !answerHidden;
revealBtn.textContent = answerHidden ? 'Show Answer' : 'Hide Answer';
if (input.value.trim().length > 0) convert();
});
hideChartBtn.addEventListener('click', function() {
chartHidden = !chartHidden;
chartWrapper.style.display = chartHidden ? 'none' : 'block';
hideChartBtn.textContent = chartHidden ? 'Show Chart' : 'Hide Chart';
});
renderEmpty();
})();
</script>
</body>
</html>