<div class="wrapper">
<h1>Bitwise Calculator</h1>
<p>Bitwise calculations convert human-readable base-10 integers into machine-readable base-2 (binary) values. They then compare each bit according to an operator and convert the result back to base-10.</p>
<p>The operators are "&" (and), "|" (or), and "^" (exclusive or).</p>
<p>You can imagine the operators working like light switches:</p>
<ul>
<li>& = both switches in the "on" position turns the light on</li>
<li>| = either switch in the "on" position turns the light on</li>
<li>^ = one switch "on" and one switch "off" turns the light on</li>
</ul>
<p>The statuses and bit flags below come from <a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition">Node.compareDocumentPosition()</a></p>
<table>
<thead>
<tr>
<th>Status</th>
<th>Bit Flag</th>
<th>Value 1</th>
<th></th>
<th>Value 2</th>
<th></th>
<th>Output</th>
</tr>
</thead>
<tbody>
<tr>
<td>DISCONNECTED</td>
<td>1</td>
<td><input type="checkbox" column="value1"></td>
<td></td>
<td><input type="checkbox" column="value2"></td>
<td></td>
<td><input type="checkbox" column="output" inert></td>
</tr>
<tr>
<td>PRECEDING</td>
<td>2</td>
<td><input type="checkbox" column="value1"></td>
<td></td>
<td><input type="checkbox" column="value2"></td>
<td></td>
<td><input type="checkbox" column="output" inert></td>
</tr>
<tr>
<td>FOLLOWING</td>
<td>4</td>
<td><input type="checkbox" column="value1"></td>
<td></td>
<td><input type="checkbox" column="value2"></td>
<td></td>
<td><input type="checkbox" column="output" inert></td>
</tr>
<tr>
<td>CONTAINS</td>
<td>8</td>
<td><input type="checkbox" column="value1"></td>
<td></td>
<td><input type="checkbox" column="value2"></td>
<td></td>
<td><input type="checkbox" column="output" inert></td>
</tr>
<tr>
<td>CONTAINED BY</td>
<td>16</td>
<td><input type="checkbox" column="value1"></td>
<td></td>
<td><input type="checkbox" column="value2"></td>
<td></td>
<td><input type="checkbox" column="output" inert></td>
</tr>
<tr>
<td>IMPLEMENTATION<br />SPECIFIC</td>
<td>32</td>
<td><input type="checkbox" column="value1"></td>
<td></td>
<td><input type="checkbox" column="value2"></td>
<td></td>
<td><input type="checkbox" column="output" inert></td>
</tr>
</tbody>
<tfoot>
<tr>
<td></td>
<td></td>
<td><input type="number" name="value1" id="value1"></td>
<td>
<select name="operator" id="operator">
<option value="&">&</option>
<option value="|">|</option>
<option value="^">^</option>
</select>
</td>
<td><input type="number" name="value2" id="value2"></td>
<td>=</td>
<td><input type="number" name="output" id="output" inert></td>
</tr>
</tfoot>
</table>
</div>
.wrapper {
max-width: 600px;
margin: 0 auto;
padding: 1rem;
}
table {
border-collapse: collapse;
border: 1px solid #bbb;
box-shadow: 0 0.75rem 1.5rem #aaa;
margin-top: 2rem;
}
td,
th {
padding: 0.25rem 0.5rem;
text-align: center;
&:first-child,
&:nth-child(2) {
text-align: left;
}
}
td:nth-child(-n + 2) {
font-family: monospace;
font-size: 1rem;
}
th,
tr:nth-child(even) {
background-color: #ddd;
}
input[type="number"],
select {
width: 7ch;
text-align: center;
}
View Compiled
console.clear();
const checkboxes = {
all: document.querySelectorAll('input[type="checkbox"][column^="value"]'),
value1: document.querySelectorAll('input[type="checkbox"][column="value1"]'),
value2: document.querySelectorAll('input[type="checkbox"][column="value2"]'),
output: document.querySelectorAll('input[type="checkbox"][column="output"]')
};
const inputs = {
all: document.querySelectorAll('input[type="number"], select'),
value1: document.querySelector("#value1"),
operator: document.querySelector("#operator"),
value2: document.querySelector("#value2"),
output: document.querySelector("#output")
};
// Limit to 6 bits since we only go to 32.
const maxBits = 6;
checkboxes.all.forEach((checkbox) =>
checkbox.addEventListener("input", updateForm)
);
inputs.all.forEach((input) =>
input.addEventListener("input", updateCheckboxes)
);
function updateForm() {
const value1 = [];
const value2 = [];
checkboxes.value1.forEach((box) => {
value1.push(box.checked + 0);
});
checkboxes.value2.forEach((box) => {
value2.push(box.checked + 0);
});
inputs.value1.value = parseInt(value1.reverse().join(""), 2);
inputs.value2.value = parseInt(value2.reverse().join(""), 2);
setTimeout(updateCheckboxes, 0);
}
function updateCheckboxes() {
const value1 = parseInt(inputs.value1.value) || 0;
const value2 = parseInt(inputs.value2.value) || 0;
const operator = inputs.operator.value;
let output = 0;
switch (operator) {
case "&":
output = value1 & value2;
break;
case "|":
output = value1 | value2;
break;
case "^":
output = value1 ^ value2;
break;
default:
break;
}
inputs.output.value = output;
const bitmask1 = value1
.toString(2)
.padStart(maxBits, "0")
.split("")
.reverse();
const bitmask2 = value2
.toString(2)
.padStart(maxBits, "0")
.split("")
.reverse();
const bitmask3 = output
.toString(2)
.padStart(maxBits, "0")
.split("")
.reverse();
bitmask1.forEach((bit, i) => {
if (i < maxBits) {
checkboxes.value1[i].checked = parseInt(bit);
}
});
bitmask2.forEach((bit, i) => {
if (i < maxBits) {
checkboxes.value2[i].checked = parseInt(bit);
}
});
bitmask3.forEach((bit, i) => {
if (i < maxBits) {
checkboxes.output[i].checked = parseInt(bit);
}
});
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.