From 512a5ff8ada075beb18bfbb9dd91f4b351808c27 Mon Sep 17 00:00:00 2001 From: Alexander Lyall Date: Sun, 14 Dec 2025 20:00:01 +0000 Subject: [PATCH] Tweaks to Binary UI Signed-off-by: Alexander Lyall --- public/scripts/binary.js | 338 ++++++++++++++++------------------- src/components/Footer.astro | 13 ++ src/components/Header.astro | 22 +++ src/layouts/BaseLayout.astro | 21 ++- src/pages/binary.astro | 25 ++- src/styles/binary.css | 300 ++++++++++++++++++++++++++----- 6 files changed, 465 insertions(+), 254 deletions(-) create mode 100644 src/components/Footer.astro create mode 100644 src/components/Header.astro diff --git a/public/scripts/binary.js b/public/scripts/binary.js index 8effa3c..443272d 100644 --- a/public/scripts/binary.js +++ b/public/scripts/binary.js @@ -1,10 +1,3 @@ -/* Binary simulator for Computing:Box - - Wrap bits every 8 (CSS handles layout) - - Bit width 4..64 - - Unsigned + Two’s complement toggle (WORKING) - - Bulbs + toggle switches for each bit -*/ - const bitsGrid = document.getElementById("bitsGrid"); const denaryEl = document.getElementById("denaryNumber"); const binaryEl = document.getElementById("binaryNumber"); @@ -21,42 +14,87 @@ const btnShiftRight = document.getElementById("btnShiftRight"); const btnCustomBinary = document.getElementById("btnCustomBinary"); const btnCustomDenary = document.getElementById("btnCustomDenary"); -let bitCount = clampInt(Number(bitsInput?.value ?? 8), 4, 64); -let isTwos = false; +let bitCount = 8; // 4..64 +let mode = "unsigned"; // "unsigned" | "twos" // bits[0] is MSB, bits[bitCount-1] is LSB let bits = new Array(bitCount).fill(false); +/* ----------------------------- + Helpers +----------------------------- */ function clampInt(n, min, max) { n = Number(n); - if (!Number.isInteger(n)) n = min; - return Math.max(min, Math.min(max, n)); + if (!Number.isFinite(n)) return min; + return Math.max(min, Math.min(max, Math.trunc(n))); } -function pow2(exp) { - // safe up to 2^63 in JS integer precision? (JS uses float) but our usage is display/control, ok. - return 2 ** exp; +function maxUnsigned(nBits) { + return (2 ** nBits) - 1; +} + +function minTwos(nBits) { + return -(2 ** (nBits - 1)); +} + +function maxTwos(nBits) { + return (2 ** (nBits - 1)) - 1; +} + +function bitsToUnsigned() { + // MSB..LSB + let v = 0; + for (let i = 0; i < bitCount; i++) { + if (bits[i]) v += 2 ** (bitCount - 1 - i); + } + return v; +} + +function bitsToSigned() { + const u = bitsToUnsigned(); + if (mode !== "twos") return u; + // if MSB is 1 => negative + if (!bits[0]) return u; + return u - (2 ** bitCount); +} + +function setBitsFromUnsigned(u) { + u = clampInt(u, 0, maxUnsigned(bitCount)); + for (let i = 0; i < bitCount; i++) { + const place = 2 ** (bitCount - 1 - i); + bits[i] = u >= place; + if (bits[i]) u -= place; + } +} + +function setBitsFromSigned(s) { + // convert signed -> unsigned representation + const min = minTwos(bitCount); + const max = maxTwos(bitCount); + s = clampInt(s, min, max); + const u = s < 0 ? (2 ** bitCount) + s : s; + setBitsFromUnsigned(u); } /* ----------------------------- - Build UI (bulbs + switches) + Build UI ----------------------------- */ -function buildBits(count) { - bitCount = clampInt(count, 4, 64); - bits = resizeBits(bits, bitCount); - +function buildBitsUI() { bitsGrid.innerHTML = ""; + // Force wrap every 8 bits visually + // CSS already does repeat(8,...). Nothing else needed. + for (let i = 0; i < bitCount; i++) { - const exp = bitCount - 1 - i; // MSB has highest exponent - const value = pow2(exp); + const placeValue = 2 ** (bitCount - 1 - i); const bit = document.createElement("div"); bit.className = "bit"; + bit.innerHTML = ` - -
${value}
-