Matematicheskiye_obosnovani.../lab1/convert.js
2025-01-29 16:04:11 +03:00

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;
}