195 lines
5.6 KiB
JavaScript
195 lines
5.6 KiB
JavaScript
import { alloc } from "./alloc.js";
|
|
import { bin2dec, bin2hex, bin2oct, dec2bin, hex2bin, oct2bin } from "./convert.js";
|
|
import { neg } from "./neg.js";
|
|
import { not } from "./not.js";
|
|
import { parse } from "./parse.js";
|
|
import { string } from "./string.js";
|
|
import { __throw } from "./utils.js";
|
|
|
|
export const kBuffer = Symbol("buffer");
|
|
|
|
/**
|
|
* @typedef { 2 | 8 | 16 | 10 } Radix
|
|
*/
|
|
|
|
export class Num {
|
|
|
|
/**
|
|
* @param { string } value
|
|
*/
|
|
static parse(value) {
|
|
/**@type { Radix } */
|
|
let radix = 10;
|
|
if (value.startsWith("0b")) radix = 2;
|
|
else if (value.startsWith("0o")) radix = 8;
|
|
else if (value.startsWith("0x")) radix = 16;
|
|
const buff = alloc(radix);
|
|
if (radix !== 10) value = value.substring(2);
|
|
if (value === "") throw new Error("unexpected end of seaquence")
|
|
|
|
parse(radix, value, buff);
|
|
return new Num(radix, buff);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param { Radix } radix
|
|
* @param { symbol[] } buffer
|
|
* @returns
|
|
*/
|
|
constructor(radix, buffer) {
|
|
this.radix = radix;
|
|
this[kBuffer] = buffer;
|
|
}
|
|
|
|
/**
|
|
* @readonly
|
|
* @type { Radix }
|
|
*/
|
|
radix;
|
|
|
|
copy() {
|
|
return new Num(this.radix, [...this[kBuffer]]);
|
|
}
|
|
|
|
toString() {
|
|
/**@type { Num } */
|
|
let target = this;
|
|
const negative = neg(target);
|
|
if (negative) not((target = target.copy()));
|
|
return negative ? `-${ string(target) }` : string(target);
|
|
}
|
|
|
|
/**
|
|
* @param { Radix } radix
|
|
* @returns { Num }
|
|
*/
|
|
as(radix) {
|
|
if (this.radix == radix) return this.copy();
|
|
if (radix == 2) {
|
|
switch (this.radix) {
|
|
case 8: return oct2bin(this);
|
|
case 16: return hex2bin(this);
|
|
case 10: return dec2bin(this);
|
|
default: throw new Error();
|
|
}
|
|
} else if (this.radix == 2) {
|
|
switch (radix) {
|
|
case 8: return bin2oct(this);
|
|
case 16: return bin2hex(this);
|
|
case 10: return bin2dec(this);
|
|
default: throw new Error();
|
|
}
|
|
}
|
|
return this.as(2).as(radix);
|
|
}
|
|
|
|
/**@see https://github.com/microsoft/TypeScript/issues/60590 */
|
|
// /**
|
|
// * @protected
|
|
// * @type { symbol[] }
|
|
// */
|
|
// [kBuffer];
|
|
}
|
|
|
|
export const one16 = Num.parse("0x1");
|
|
export const one8 = Num.parse("0o1");
|
|
export const one2 = Num.parse("0b1");
|
|
export const one10 = Num.parse("1");
|
|
|
|
export const dec2p0 = Num.parse("1");
|
|
export const dec2p0neg = dec2p0.copy();
|
|
not(dec2p0neg);
|
|
export const dec2p1 = Num.parse("2");
|
|
export const dec2p1neg = dec2p1.copy();
|
|
not(dec2p1neg);
|
|
export const dec2p2 = Num.parse("4");
|
|
export const dec2p2neg = dec2p2.copy();
|
|
not(dec2p2neg);
|
|
export const dec2p3 = Num.parse("8");
|
|
export const dec2p3neg = dec2p3.copy();
|
|
not(dec2p3neg);
|
|
export const dec2p4 = Num.parse("16");
|
|
export const dec2p4neg = dec2p4.copy();
|
|
not(dec2p4neg);
|
|
export const dec2p5 = Num.parse("32");
|
|
export const dec2p5neg = dec2p5.copy();
|
|
not(dec2p5neg);
|
|
export const dec2p6 = Num.parse("64");
|
|
export const dec2p6neg = dec2p6.copy();
|
|
not(dec2p6neg);
|
|
export const dec2p7 = Num.parse("128");
|
|
export const dec2p7neg = dec2p7.copy();
|
|
not(dec2p7neg);
|
|
export const dec2p8 = Num.parse("256");
|
|
export const dec2p8neg = dec2p8.copy();
|
|
not(dec2p8neg);
|
|
export const dec2p9 = Num.parse("512");
|
|
export const dec2p9neg = dec2p9.copy();
|
|
not(dec2p9neg);
|
|
export const dec2p10 = Num.parse("1024");
|
|
export const dec2p10neg = dec2p10.copy();
|
|
not(dec2p10neg);
|
|
export const dec2p11 = Num.parse("2048");
|
|
export const dec2p11neg = dec2p11.copy();
|
|
not(dec2p11neg);
|
|
export const dec2p12 = Num.parse("4096");
|
|
export const dec2p12neg = dec2p12.copy();
|
|
not(dec2p12neg);
|
|
export const dec2p13 = Num.parse("8192");
|
|
export const dec2p13neg = dec2p13.copy();
|
|
not(dec2p13neg);
|
|
export const dec2p14 = Num.parse("16384");
|
|
export const dec2p14neg = dec2p14.copy();
|
|
not(dec2p14neg);
|
|
export const dec2p15 = Num.parse("32768");
|
|
export const dec2p15neg = dec2p15.copy();
|
|
not(dec2p15neg);
|
|
export const dec2p16 = Num.parse("65536");
|
|
export const dec2p16neg = dec2p16.copy();
|
|
not(dec2p16neg);
|
|
export const dec2p17 = Num.parse("131072");
|
|
export const dec2p17neg = dec2p17.copy();
|
|
not(dec2p17neg);
|
|
export const dec2p18 = Num.parse("262144");
|
|
export const dec2p18neg = dec2p18.copy();
|
|
not(dec2p18neg);
|
|
export const dec2p19 = Num.parse("524288");
|
|
export const dec2p19neg = dec2p19.copy();
|
|
not(dec2p19neg);
|
|
export const dec2p20 = Num.parse("1048576");
|
|
export const dec2p20neg = dec2p20.copy();
|
|
not(dec2p20neg);
|
|
export const dec2p21 = Num.parse("2097152");
|
|
export const dec2p21neg = dec2p21.copy();
|
|
not(dec2p21neg);
|
|
export const dec2p22 = Num.parse("4194304");
|
|
export const dec2p22neg = dec2p22.copy();
|
|
not(dec2p22neg);
|
|
export const dec2p23 = Num.parse("8388608");
|
|
export const dec2p23neg = dec2p23.copy();
|
|
not(dec2p23neg);
|
|
export const dec2p24 = Num.parse("16777216");
|
|
export const dec2p24neg = dec2p24.copy();
|
|
not(dec2p24neg);
|
|
export const dec2p25 = Num.parse("33554432");
|
|
export const dec2p25neg = dec2p25.copy();
|
|
not(dec2p25neg);
|
|
export const dec2p26 = Num.parse("67108864");
|
|
export const dec2p26neg = dec2p26.copy();
|
|
not(dec2p26neg);
|
|
export const dec2p27 = Num.parse("134217728");
|
|
export const dec2p27neg = dec2p27.copy();
|
|
not(dec2p27neg);
|
|
export const dec2p28 = Num.parse("268435456");
|
|
export const dec2p28neg = dec2p28.copy();
|
|
not(dec2p28neg);
|
|
export const dec2p29 = Num.parse("536870912");
|
|
export const dec2p29neg = dec2p29.copy();
|
|
not(dec2p29neg);
|
|
export const dec2p30 = Num.parse("1073741824");
|
|
export const dec2p30neg = dec2p30.copy();
|
|
not(dec2p30neg);
|
|
export const dec2p31 = Num.parse("2147483648");
|
|
export const dec2p31neg = dec2p31.copy();
|
|
not(dec2p31neg); |