403 lines
12 KiB
JavaScript
403 lines
12 KiB
JavaScript
import { Num, dec2p0neg, dec2p1neg, dec2p2neg, dec2p3neg, dec2p4neg, dec2p5neg, dec2p6neg, dec2p7neg, dec2p8neg, dec2p9neg, dec2p10neg, dec2p11neg, dec2p12neg, dec2p13neg, dec2p14neg, dec2p15neg, dec2p16neg, dec2p17neg, dec2p18neg, dec2p19neg, dec2p20neg, dec2p21neg, dec2p22neg, dec2p23neg, dec2p24neg, dec2p25neg, dec2p26neg, dec2p27neg, dec2p28neg, dec2p29neg, dec2p30neg, dec2p31neg, dec2p0, dec2p1, dec2p2, dec2p3, dec2p4, dec2p5, dec2p6, dec2p7, dec2p8, dec2p9, dec2p10, dec2p11, dec2p12, dec2p13, dec2p14, dec2p15, dec2p16, dec2p17, dec2p18, dec2p19, dec2p20, dec2p21, dec2p22, dec2p23, dec2p24, dec2p25, dec2p26, dec2p27, dec2p28, dec2p29, dec2p30, dec2p31, kBuffer } from "./num.js";
|
|
import { alloc, size2 } from "./alloc.js"
|
|
import { add } from "./add.js";
|
|
import { neg } from "./neg.js";
|
|
import { S2_0, S2_1 } from "./symbol/S2.js";
|
|
import { not } from "./not.js";
|
|
import { S16_0, S16_1, S16_2, S16_3, S16_4, S16_5, S16_6, S16_7, S16_8, S16_9, S16_A, S16_B, S16_C, S16_D, S16_E, S16_F } from "./symbol/S16.js";
|
|
import { S8_0, S8_1, S8_2, S8_3, S8_4, S8_5, S8_6, S8_7 } from "./symbol/S8.js";
|
|
|
|
/**
|
|
* @param { number } i
|
|
*/
|
|
function subtrahend(i) {
|
|
switch (i) {
|
|
case 0: return dec2p0neg;
|
|
case 1: return dec2p1neg;
|
|
case 2: return dec2p2neg;
|
|
case 3: return dec2p3neg;
|
|
case 4: return dec2p4neg;
|
|
case 5: return dec2p5neg;
|
|
case 6: return dec2p6neg;
|
|
case 7: return dec2p7neg;
|
|
case 8: return dec2p8neg;
|
|
case 9: return dec2p9neg;
|
|
case 10: return dec2p10neg;
|
|
case 11: return dec2p11neg;
|
|
case 12: return dec2p12neg;
|
|
case 13: return dec2p13neg;
|
|
case 14: return dec2p14neg;
|
|
case 15: return dec2p15neg;
|
|
case 16: return dec2p16neg;
|
|
case 17: return dec2p17neg;
|
|
case 18: return dec2p18neg;
|
|
case 19: return dec2p19neg;
|
|
case 20: return dec2p20neg;
|
|
case 21: return dec2p21neg;
|
|
case 22: return dec2p22neg;
|
|
case 23: return dec2p23neg;
|
|
case 24: return dec2p24neg;
|
|
case 25: return dec2p25neg;
|
|
case 26: return dec2p26neg;
|
|
case 27: return dec2p27neg;
|
|
case 28: return dec2p28neg;
|
|
case 29: return dec2p29neg;
|
|
case 30: return dec2p30neg;
|
|
case 31: return dec2p31neg;
|
|
default: throw new Error(`unexpected index (${i})`)
|
|
}
|
|
}
|
|
|
|
function addend(i) {
|
|
switch (i) {
|
|
case 0: return dec2p0;
|
|
case 1: return dec2p1;
|
|
case 2: return dec2p2;
|
|
case 3: return dec2p3;
|
|
case 4: return dec2p4;
|
|
case 5: return dec2p5;
|
|
case 6: return dec2p6;
|
|
case 7: return dec2p7;
|
|
case 8: return dec2p8;
|
|
case 9: return dec2p9;
|
|
case 10: return dec2p10;
|
|
case 11: return dec2p11;
|
|
case 12: return dec2p12;
|
|
case 13: return dec2p13;
|
|
case 14: return dec2p14;
|
|
case 15: return dec2p15;
|
|
case 16: return dec2p16;
|
|
case 17: return dec2p17;
|
|
case 18: return dec2p18;
|
|
case 19: return dec2p19;
|
|
case 20: return dec2p20;
|
|
case 21: return dec2p21;
|
|
case 22: return dec2p22;
|
|
case 23: return dec2p23;
|
|
case 24: return dec2p24;
|
|
case 25: return dec2p25;
|
|
case 26: return dec2p26;
|
|
case 27: return dec2p27;
|
|
case 28: return dec2p28;
|
|
case 29: return dec2p29;
|
|
case 30: return dec2p30;
|
|
case 31: return dec2p31;
|
|
default: throw new Error(`unexpected index (${i})`)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param { Num } a
|
|
*/
|
|
function udec2bin(a) {
|
|
const buff = alloc(2);
|
|
for (let i = size2 - 1; i >= 0; i--) {
|
|
let b = a.copy();
|
|
add(b, subtrahend(i));
|
|
if (!neg(b)) {
|
|
a = b;
|
|
buff[i] = S2_1;
|
|
}
|
|
}
|
|
return new Num(2, buff);
|
|
}
|
|
/**
|
|
* @param { Num } a
|
|
*/
|
|
export function dec2bin(a) {
|
|
const negative = neg(a);
|
|
if (negative) {
|
|
a = a.copy();
|
|
not(a);
|
|
}
|
|
const result = udec2bin(a);
|
|
if (negative) not(result);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @param { Num } a
|
|
*/
|
|
function ubin2dec(a) {
|
|
const result = new Num(10, alloc(10));
|
|
const { [kBuffer]: buff } = a;
|
|
for (let i = 0; i < size2; i++) {
|
|
if (buff[i] == S2_1) add(result, addend(i));
|
|
}
|
|
return result
|
|
}
|
|
/**
|
|
* @param { Num } a
|
|
*/
|
|
export function bin2dec(a) {
|
|
const negative = neg(a);
|
|
if (negative) {
|
|
a = a.copy();
|
|
not(a);
|
|
}
|
|
const result = ubin2dec(a);
|
|
if (negative) not(result);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @param { symbol } a
|
|
* @param { symbol } b
|
|
* @param { symbol } c
|
|
* @param { symbol } d
|
|
*/
|
|
function ubin2hexB(d, c, b, a) {
|
|
switch (a) {
|
|
case S2_0: switch (b) {
|
|
case S2_0: switch (c) {
|
|
case S2_0: switch (d) {
|
|
case S2_0: return S16_0;
|
|
case S2_1: return S16_1;
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
case S2_1: switch (d) {
|
|
case S2_0: return S16_2;
|
|
case S2_1: return S16_3;
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
case S2_1: switch (c) {
|
|
case S2_0: switch (d) {
|
|
case S2_0: return S16_4;
|
|
case S2_1: return S16_5;
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
case S2_1: switch (d) {
|
|
case S2_0: return S16_6;
|
|
case S2_1: return S16_7;
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
}
|
|
case S2_1: switch (b) {
|
|
case S2_0: switch (c) {
|
|
case S2_0: switch (d) {
|
|
case S2_0: return S16_8;
|
|
case S2_1: return S16_9;
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
case S2_1: switch (d) {
|
|
case S2_0: return S16_A;
|
|
case S2_1: return S16_B;
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
case S2_1: switch (c) {
|
|
case S2_0: switch (d) {
|
|
case S2_0: return S16_C;
|
|
case S2_1: return S16_D;
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
case S2_1: switch (d) {
|
|
case S2_0: return S16_E;
|
|
case S2_1: return S16_F;
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
}
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param { Num } a
|
|
*/
|
|
function ubin2hex(a) {
|
|
const buff = alloc(16);
|
|
const { [kBuffer]: buffer } = a;
|
|
for (let i = 0; i < buff.length; i++) {
|
|
const a = buffer[(i * 4)] ?? S2_0;
|
|
const b = buffer[(i * 4) + 1] ?? S2_0;
|
|
const c = buffer[(i * 4) + 2] ?? S2_0;
|
|
const d = buffer[(i * 4) + 3] ?? S2_0;
|
|
buff[i] = ubin2hexB(a, b, c, d);
|
|
}
|
|
return new Num(16, buff);
|
|
}
|
|
/**
|
|
* @param { Num } a
|
|
*/
|
|
export function bin2hex(a) {
|
|
const negative = neg(a);
|
|
if (negative) {
|
|
a = a.copy();
|
|
not(a);
|
|
}
|
|
const result = ubin2hex(a);
|
|
if (negative) not(result);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @param { symbol } a
|
|
* @returns { [symbol, symbol, symbol, symbol] }
|
|
*/
|
|
function uhex2binB(a) {
|
|
switch (a) {
|
|
case S16_0: return [S2_0, S2_0, S2_0, S2_0];
|
|
case S16_1: return [S2_0, S2_0, S2_0, S2_1];
|
|
case S16_2: return [S2_0, S2_0, S2_1, S2_0];
|
|
case S16_3: return [S2_0, S2_0, S2_1, S2_1];
|
|
case S16_4: return [S2_0, S2_1, S2_0, S2_0];
|
|
case S16_5: return [S2_0, S2_1, S2_0, S2_1];
|
|
case S16_6: return [S2_0, S2_1, S2_1, S2_0];
|
|
case S16_7: return [S2_0, S2_1, S2_1, S2_1];
|
|
case S16_8: return [S2_1, S2_0, S2_0, S2_0];
|
|
case S16_9: return [S2_1, S2_0, S2_0, S2_1];
|
|
case S16_A: return [S2_1, S2_0, S2_1, S2_0];
|
|
case S16_B: return [S2_1, S2_0, S2_1, S2_1];
|
|
case S16_C: return [S2_1, S2_1, S2_0, S2_0];
|
|
case S16_D: return [S2_1, S2_1, S2_0, S2_1];
|
|
case S16_E: return [S2_1, S2_1, S2_1, S2_0];
|
|
case S16_F: return [S2_1, S2_1, S2_1, S2_1];
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param { Num } a
|
|
*/
|
|
function uhex2bin(a) {
|
|
const buff = alloc(2);
|
|
const { [kBuffer]: buffer } = a;
|
|
for (let i = 0; i < buffer.length; i++) {
|
|
const [d, c, b, a] = uhex2binB(buffer[i]);
|
|
if ((i * 4) < buff.length) buff[(i * 4)] = a;
|
|
if ((i * 4) + 1 < buff.length) buff[(i * 4) + 1] = b;
|
|
if ((i * 4) + 2 < buff.length) buff[(i * 4) + 2] = c;
|
|
if ((i * 4) + 3< buff.length) buff[(i * 4) + 3] = d;
|
|
}
|
|
return new Num(2, buff);
|
|
}
|
|
/**
|
|
* @param { Num } a
|
|
*/
|
|
export function hex2bin(a) {
|
|
const negative = neg(a);
|
|
if (negative) {
|
|
a = a.copy();
|
|
not(a);
|
|
}
|
|
const result = uhex2bin(a);
|
|
if (negative) not(result);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @param { symbol } a
|
|
* @param { symbol } b
|
|
* @param { symbol } c
|
|
*/
|
|
function ubin2octB(c, b, a) {
|
|
switch (a) {
|
|
case S2_0: switch (b) {
|
|
case S2_0: switch (c) {
|
|
case S2_0: return S8_0;
|
|
case S2_1: return S8_1;
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
case S2_1: switch (c) {
|
|
case S2_0: return S8_2;
|
|
case S2_1: return S8_3;
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
case S2_1: switch (b) {
|
|
case S2_0: switch (c) {
|
|
case S2_0: return S8_4;
|
|
case S2_1: return S8_5;
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
case S2_1: switch (c) {
|
|
case S2_0: return S8_6;
|
|
case S2_1: return S8_7;
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param { Num } a
|
|
*/
|
|
function ubin2oct(a) {
|
|
const buff = alloc(8);
|
|
const { [kBuffer]: buffer } = a;
|
|
for (let i = 0; i < buff.length; i++) {
|
|
const a = buffer[(i * 3)] ?? S2_0;
|
|
const b = buffer[(i * 3) + 1] ?? S2_0;
|
|
const c = buffer[(i * 3) + 2] ?? S2_0;
|
|
buff[i] = ubin2octB(a, b, c);
|
|
}
|
|
return new Num(8, buff);
|
|
}
|
|
/**
|
|
* @param { Num } a
|
|
*/
|
|
export function bin2oct(a) {
|
|
const negative = neg(a);
|
|
if (negative) {
|
|
a = a.copy();
|
|
not(a);
|
|
}
|
|
const result = ubin2oct(a);
|
|
if (negative) not(result);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @param { symbol } a
|
|
* @returns { [symbol, symbol, symbol] }
|
|
*/
|
|
function uoct2binB(a) {
|
|
switch (a) {
|
|
case S8_0: return [S2_0, S2_0, S2_0];
|
|
case S8_1: return [S2_0, S2_0, S2_1];
|
|
case S8_2: return [S2_0, S2_1, S2_0];
|
|
case S8_3: return [S2_0, S2_1, S2_1];
|
|
case S8_4: return [S2_1, S2_0, S2_0];
|
|
case S8_5: return [S2_1, S2_0, S2_1];
|
|
case S8_6: return [S2_1, S2_1, S2_0];
|
|
case S8_7: return [S2_1, S2_1, S2_1];
|
|
default: throw new Error("unexpected symbol");
|
|
}
|
|
}
|
|
/**
|
|
* @param { Num } a
|
|
*/
|
|
function uoct2bin(a) {
|
|
const buff = alloc(2);
|
|
const { [kBuffer]: buffer } = a;
|
|
for (let i = 0; i < buffer.length; i++) {
|
|
const [c, b, a] = uoct2binB(buffer[i]);
|
|
if ((i * 3) < buff.length) buff[(i * 3)] = a;
|
|
if ((i * 3) + 1 < buff.length) buff[(i * 3) + 1] = b;
|
|
if ((i * 3) + 2 < buff.length) buff[(i * 3) + 2] = c;
|
|
}
|
|
return new Num(2, buff);
|
|
}
|
|
/**
|
|
* @param { Num } a
|
|
*/
|
|
export function oct2bin(a) {
|
|
const negative = neg(a);
|
|
if (negative) {
|
|
a = a.copy();
|
|
not(a);
|
|
}
|
|
const result = uoct2bin(a);
|
|
if (negative) not(result);
|
|
return result;
|
|
} |