diff --git a/package.json b/package.json index d51f503..27caf2c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "computing-box", + "name": "Computing:Box", "type": "module", - "version": "0.0.1", + "version": "2.0.0 Alpha", "scripts": { "dev": "astro dev", "build": "astro build", diff --git a/public/scripts/binary.js b/public/scripts/binary.js deleted file mode 100644 index 4733635..0000000 --- a/public/scripts/binary.js +++ /dev/null @@ -1,263 +0,0 @@ -const bitsRows = document.getElementById("bitsRows"); -const denaryEl = document.getElementById("denaryNumber"); -const binaryEl = document.getElementById("binaryNumber"); - -const modeToggle = document.getElementById("modeToggle"); -const modeHint = document.getElementById("modeHint"); - -const bitsInput = document.getElementById("bitsInput"); -const btnBitsUp = document.getElementById("btnBitsUp"); -const btnBitsDown = document.getElementById("btnBitsDown"); - -const btnShiftLeft = document.getElementById("btnShiftLeft"); -const btnShiftRight = document.getElementById("btnShiftRight"); -const btnCustomBinary = document.getElementById("btnCustomBinary"); -const btnCustomDenary = document.getElementById("btnCustomDenary"); - -let bitCount = clampInt(Number(bitsInput.value || 8), 1, 64); -let bits = new Array(bitCount).fill(false); // index 0 = MSB - -function clampInt(n, min, max){ - n = Number(n); - if (!Number.isFinite(n)) n = min; - n = Math.floor(n); - return Math.max(min, Math.min(max, n)); -} - -function isTwos(){ - return !!modeToggle.checked; -} - -function msbValue(){ - return 2 ** (bitCount - 1); -} - -function unsignedValueAt(i){ - // i=0 is MSB - return 2 ** (bitCount - 1 - i); -} - -function computeUnsigned(){ - let sum = 0; - for (let i = 0; i < bitCount; i++){ - if (bits[i]) sum += unsignedValueAt(i); - } - return sum; -} - -function computeDenary(){ - const u = computeUnsigned(); - if (!isTwos()) return u; - - // Two's complement: - // if MSB is 1, value = unsigned - 2^n - if (bits[0]) return u - (2 ** bitCount); - return u; -} - -function bitsToString(){ - return bits.map(b => (b ? "1" : "0")).join(""); -} - -function updateModeHint(){ - if (isTwos()){ - modeHint.textContent = "Tip: In two's complement, the left-most bit (MSB) represents a negative value."; - } else { - modeHint.textContent = "Tip: In unsigned binary, all bits represent positive values."; - } -} - -function buildBitsUI(){ - bitsRows.innerHTML = ""; - - // Build rows of 8 bits - const rowCount = Math.ceil(bitCount / 8); - - for (let r = 0; r < rowCount; r++){ - const row = document.createElement("div"); - row.className = "byteRow"; - - const start = r * 8; - const end = Math.min(start + 8, bitCount); - - for (let i = start; i < end; i++){ - const bitEl = document.createElement("div"); - bitEl.className = "bit"; - - // label: show -MSB in two's complement - const labelVal = (isTwos() && i === 0) ? -msbValue() : unsignedValueAt(i); - - bitEl.innerHTML = ` - -
${labelVal}
- - `; - - row.appendChild(bitEl); - } - - bitsRows.appendChild(row); - } - - // Hook switches - bitsRows.querySelectorAll('input[type="checkbox"][data-index]').forEach(input => { - input.addEventListener("change", () => { - const i = Number(input.dataset.index); - bits[i] = input.checked; - updateReadout(); - }); - }); - - syncUI(); -} - -function syncUI(){ - // sync inputs - bitsRows.querySelectorAll('input[type="checkbox"][data-index]').forEach(input => { - const i = Number(input.dataset.index); - input.checked = !!bits[i]; - }); - - // sync bulbs - for (let i = 0; i < bitCount; i++){ - const bulb = document.getElementById(`bulb-${i}`); - if (bulb) bulb.classList.toggle("on", !!bits[i]); - } - - updateReadout(); -} - -function updateReadout(){ - denaryEl.textContent = String(computeDenary()); - binaryEl.textContent = bitsToString(); -} - -function setFromBinary(bin){ - const clean = String(bin).replace(/\s+/g, ""); - if (!/^[01]+$/.test(clean)) return false; - - const padded = clean.slice(-bitCount).padStart(bitCount, "0"); - for (let i = 0; i < bitCount; i++){ - bits[i] = padded[i] === "1"; - } - - syncUI(); - return true; -} - -function setFromDenary(n){ - n = Number(n); - if (!Number.isInteger(n)) return false; - - if (!isTwos()){ - // unsigned: 0 .. (2^n - 1) - const max = (2 ** bitCount) - 1; - if (n < 0 || n > max) return false; - - for (let i = 0; i < bitCount; i++){ - const v = unsignedValueAt(i); - if (n >= v){ - bits[i] = true; - n -= v; - } else { - bits[i] = false; - } - } - syncUI(); - return true; - } - - // two's complement: -(2^(n-1)) .. (2^(n-1)-1) - const min = -(2 ** (bitCount - 1)); - const max = (2 ** (bitCount - 1)) - 1; - if (n < min || n > max) return false; - - // convert to unsigned representation - let u = n; - if (u < 0) u = (2 ** bitCount) + u; // wrap - - for (let i = 0; i < bitCount; i++){ - const v = unsignedValueAt(i); - if (u >= v){ - bits[i] = true; - u -= v; - } else { - bits[i] = false; - } - } - - syncUI(); - return true; -} - -function shiftLeft(){ - bits.shift(); // drop MSB - bits.push(false); // add LSB - syncUI(); -} - -function shiftRight(){ - bits.pop(); // drop LSB - bits.unshift(false); // add MSB - syncUI(); -} - -function setBitCount(newCount){ - newCount = clampInt(newCount, 4, 64); - if (newCount === bitCount) return; - - // preserve right-most bits (LSB side) when resizing - const old = bits.slice(); - const next = new Array(newCount).fill(false); - - const copy = Math.min(old.length, next.length); - for (let k = 0; k < copy; k++){ - // copy from end (LSB) - next[newCount - 1 - k] = old[old.length - 1 - k]; - } - - bitCount = newCount; - bits = next; - - bitsInput.value = String(bitCount); - buildBitsUI(); -} - -/* -------------------- events -------------------- */ - -modeToggle.addEventListener("change", () => { - updateModeHint(); - buildBitsUI(); // rebuild labels (MSB becomes negative/positive) -}); - -btnBitsUp.addEventListener("click", () => setBitCount(bitCount + 1)); -btnBitsDown.addEventListener("click", () => setBitCount(bitCount - 1)); - -bitsInput.addEventListener("change", () => setBitCount(Number(bitsInput.value))); - -btnShiftLeft.addEventListener("click", shiftLeft); -btnShiftRight.addEventListener("click", shiftRight); - -btnCustomBinary.addEventListener("click", () => { - const v = prompt(`Enter ${bitCount}-bit binary:`); - if (v === null) return; - if (!setFromBinary(v)) alert("Invalid binary. Use only 0 and 1."); -}); - -btnCustomDenary.addEventListener("click", () => { - const min = isTwos() ? -(2 ** (bitCount - 1)) : 0; - const max = isTwos() ? (2 ** (bitCount - 1)) - 1 : (2 ** bitCount) - 1; - - const v = prompt(`Enter a denary number (${min} to ${max}):`); - if (v === null) return; - if (!setFromDenary(Number(v))) alert("Invalid denary for current mode/bit width."); -}); - -/* -------------------- init -------------------- */ - -bitsInput.value = String(bitCount); -updateModeHint(); -buildBitsUI(); diff --git a/src/components/Footer.astro b/src/components/Footer.astro index 443552a..2dbcdbd 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -1,7 +1,29 @@ + + diff --git a/src/components/Header.astro b/src/components/Header.astro index 7746fba..6c42d5c 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -1,13 +1,57 @@ + + diff --git a/src/components/tools/BinarySimulator.astro b/src/components/tools/BinarySimulator.astro deleted file mode 100644 index 43d5ce1..0000000 --- a/src/components/tools/BinarySimulator.astro +++ /dev/null @@ -1,381 +0,0 @@ ---- -const { mode = "unsigned", defaultBits = 8 } = Astro.props; - -// For unsigned: min 1 bit, max 16 bits (tweak if you want) -const minBits = 4; -const maxBits = 16; -const initialBits = Math.min(Math.max(defaultBits, minBits), maxBits); ---- - -
-
-
- - -
- -
-
DENARY
-
0
- -
BINARY
-
00000000
-
- -
- - - - - -
-
Bits
-
- - {initialBits} - -
-
-
-
- -
-
- - - - diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index dfca60b..c813bc3 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -11,12 +11,6 @@ const { title = "Computing:Box" } = Astro.props; {title} - - - - - - @@ -27,3 +21,15 @@ const { title = "Computing:Box" } = Astro.props;