Created
April 25, 2024 14:19
-
-
Save Mapaler/2f31717be034147334287b85aa7e0b29 to your computer and use it in GitHub Desktop.
二进制和Flags转换类
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Bin extends Set { | |
static #typeError_Constructor = "传入的不是 number 和 bigint 类型或这个两个类型的数组"; | |
static #typeError_FlagsNum = "传入的不是 number 和 bigint 类型"; | |
static #typeError_FlagsArray = "传入的不是 number 类型的数组"; | |
static #typeError_NotInteger = "传入的不是 整数"; | |
static #rangeError_NotSafe = "传入的 number 大于 53 位"; | |
/** | |
* 构建函数 | |
* @param {(number | bigint | number[])} arg 传入参数 | |
*/ | |
constructor (arg) { | |
if (typeof arg === "number" || typeof arg === "bigint") { | |
super(Bin.unflags(arg)); | |
} else if (Array.isArray(arg) && | |
arg.every(item=>typeof item === "number" && Number.isSafeInteger(item)) | |
){ | |
super(arg); | |
} else { | |
throw new TypeError(Bin.#typeError_Constructor); | |
} | |
} | |
/** | |
* 将数字或大整形flag转换为数组 | |
* @param {(number | bigint)} number 输入的数字 | |
* @returns {number[]} 输出数组 | |
*/ | |
static unflags(number) { | |
const inputType = typeof number; | |
if (inputType === "number" || inputType === "bigint"){ | |
if (inputType === "number" && number > Number.MAX_SAFE_INTEGER) { | |
throw new RangeError(Bin.#rangeError_NotSafe); | |
} | |
const isBigint = inputType === "bigint"; | |
const arr = []; | |
for (let i = 0, flag = isBigint ? 1n : 1; flag <= number; i++, flag = (isBigint ? 2n : 2) ** (isBigint ? BigInt(i) : i)) { | |
if (number & flag) { | |
arr.push(i); | |
} | |
} | |
return arr; | |
} else { | |
throw new TypeError(Bin.#typeError_FlagsNum); | |
} | |
} | |
/** | |
* 将数字序号转换为数字 | |
* @param {number[]} indexArr 输入的序号数组 | |
* @returns {(number | bigint)} 输出的数字 | |
*/ | |
static enflags(indexArr) { | |
if (Array.isArray(indexArr) && | |
indexArr.every(item=>typeof item === "number" && Number.isSafeInteger(item)) | |
){ | |
let result = 0, isBigint = false, baseNum = 2; | |
for (let i = 0; i < indexArr.length; i++) { | |
let value = indexArr[i]; | |
//当数值大于52位,即需要换BigInt | |
if (value > 52 && !isBigint) { | |
isBigint = true; | |
result = BigInt(result); | |
baseNum = BigInt(baseNum); | |
} | |
isBigint && (value = BigInt(value)); //一旦需要BigInt了,就转换 | |
result = result + baseNum ** value; //用乘方相加而不是位移的优点是可以得到 0xFFFFFFFF 而不是 -1 | |
} | |
return result; | |
} else { | |
throw new TypeError(Bin.#typeError_FlagsArray); | |
} | |
} | |
get int() { | |
return Bin.enflags(Array.from(this.values())); | |
} | |
add(index) { | |
if (typeof index === "number" && Number.isSafeInteger(index)){ | |
super.add(index); | |
} else { | |
throw new TypeError(Bin.#typeError_NotInteger); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment