bitwise-operation
Version:
JavaScript's bitwise operation helper library.
278 lines (277 loc) • 7.68 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class Bitwise {
constructor(value = 0) {
this.value = 0;
if (value instanceof Bitwise)
return value;
if (Array.isArray(value)) {
value.forEach((bit, idx) => {
this.value |= (bit ? 1 : 0) << idx;
});
}
else if (typeof value == "string") {
let idx = 0;
for (let i = value.length - 1; i >= 0; i--) {
if (value[i] === "1" || value[i] === "0") {
this.value |= (value[i] === "1" ? 1 : 0) << idx;
idx++;
}
}
}
else {
this.value = value;
}
}
static chain(value = 0) {
return new Bitwise(value);
}
static not(value) {
return ~value;
}
static and(value, ...values) {
const bitwise = new Bitwise(value);
while (values.length > 0) {
let value = values.shift();
if (value !== undefined) {
bitwise.and(value);
}
}
return bitwise.valueOf();
}
static nand(value, ...values) {
const bitwise = new Bitwise(value);
while (values.length > 0) {
let value = values.shift();
if (value !== undefined) {
bitwise.nand(value);
}
}
return bitwise.valueOf();
}
static andNot(value, ...values) {
return this.nand(value, ...values);
}
static or(value, ...values) {
const bitwise = new Bitwise(value);
while (values.length > 0) {
let value = values.shift();
if (value !== undefined) {
bitwise.or(value);
}
}
return bitwise.valueOf();
}
static nor(value, ...values) {
const bitwise = new Bitwise(value);
while (values.length > 0) {
let value = values.shift();
if (value !== undefined) {
bitwise.nor(value);
}
}
return bitwise.valueOf();
}
static xor(value, ...values) {
const bitwise = new Bitwise(value);
while (values.length > 0) {
let value = values.shift();
if (value !== undefined) {
bitwise.xor(value);
}
}
return bitwise.valueOf();
}
static xnor(value, ...values) {
const bitwise = new Bitwise(value);
while (values.length > 0) {
let value = values.shift();
if (value !== undefined) {
bitwise.xnor(value);
}
}
return bitwise.valueOf();
}
static nxor(value, ...values) {
return this.xnor(value, ...values);
}
static toggle(value, ...idx) {
const bitwise = new Bitwise(value);
while (idx.length > 0) {
let index = idx.shift();
if (index !== undefined) {
bitwise.toggle(index);
}
}
return bitwise.valueOf();
}
static swap(value, ...idx) {
const bitwise = new Bitwise(value);
while (idx.length > 0) {
let indexes = idx.shift();
if (indexes !== undefined) {
bitwise.swap(...indexes);
}
}
return bitwise.valueOf();
}
static mask(from, to) {
if (to === undefined) {
to = from;
from = 0;
}
return new Bitwise(0).setRange(from, to).valueOf();
}
not() {
this.value = ~this.value;
return this;
}
and(value) {
const bitwise = new Bitwise(value);
this.value &= bitwise.valueOf();
return this;
}
nand(value) {
this.and(value).not();
return this;
}
andNot(value) {
return this.nand(value);
}
or(value) {
const bitwise = new Bitwise(value);
this.value |= bitwise.valueOf();
return this;
}
nor(value) {
this.or(value).not();
return this;
}
xor(value) {
this.value = this.copy()
.or(value)
.and(this.copy().and(value).not())
.valueOf();
return this;
}
xnor(value) {
this.xor(value).not();
return this;
}
nxor(value) {
return this.xnor(value);
}
set(idx, value = true) {
if (value === false)
return this.unset(idx);
if (idx < 0)
return this;
this.value |= 1 << idx;
return this;
}
unset(idx) {
if (idx < 0)
return this;
this.value &= ~(1 << idx);
return this;
}
get(idx) {
if (idx < 0)
return false;
return (this.value & (1 << idx)) > 0;
}
toggle(idx) {
this.set(idx, !this.get(idx));
return this;
}
swap(idx1, idx2) {
if (idx1 < 0 || idx2 < 0)
return this;
let tmp = this.copy();
this.set(idx2, tmp.get(idx1));
this.set(idx1, tmp.get(idx2));
return this;
}
setRange(from, to) {
if (from < 0 || to < 0)
return this;
this.value |= Bitwise.xor((1 << from) - 1, ((1 << to) << 1) - 1);
return this;
}
unsetRange(from, to) {
if (from < 0 || to < 0)
return this;
this.value &= ~Bitwise.xor((1 << from) - 1, ((1 << to) << 1) - 1);
return this;
}
toggleRange(from, to) {
if (from < 0 || to < 0)
return this;
const mask = Bitwise.mask(from, to);
this.value = this.copy()
.not()
.and(mask)
.or(this.copy().and(Bitwise.not(mask)))
.valueOf();
return this;
}
mask(from, to) {
this.and(Bitwise.mask(from, to));
return this;
}
clear(from, to) {
this.and(Bitwise.not(Bitwise.mask(from, to)));
return this;
}
equals(value) {
const bitwise = new Bitwise(value);
return this.value === bitwise.value;
}
setValue(value) {
const bitwise = new Bitwise(value);
this.value = bitwise.value;
return this;
}
copy() {
return new Bitwise(this.value);
}
clone() {
return this.copy();
}
valueOf() {
return this.value;
}
toString(length, separator = " ") {
let value = this.value.toString(2);
if (length === undefined)
return value;
return value.replace(new RegExp("\\B(?=(\\d{" + length + "})+(?!\\d))", "g"), separator);
}
toArray() {
let value = this.value;
let array = [];
if (value === 0)
return [0];
while (value > 0) {
array.push((value & 1) > 0 ? 1 : 0);
value = value >> 1;
}
return array;
}
cardinality() {
const match = this.toString().match(/(1)/g);
if (!match)
return 0;
return match.length;
}
length() {
if (this.value >= 0 && Number.isSafeInteger(this.value))
return this.toString().length;
return Number.MAX_SAFE_INTEGER.toString(2).length;
}
size() {
return this.length();
}
}
Bitwise.VERSION = "2.0.1";
exports.Bitwise = Bitwise;