initial commit
This commit is contained in:
commit
79b304eb5e
72
lab1/add.js
Normal file
72
lab1/add.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* @import { Num } from "./num.js"
|
||||||
|
*/
|
||||||
|
import { kBuffer } from "./num.js";
|
||||||
|
import { add16B } from "./add/16B.js"
|
||||||
|
import { add8B } from "./add/8B.js";
|
||||||
|
import { add2B } from "./add/2B.js";
|
||||||
|
import { add10B } from "./add/10B.js";
|
||||||
|
import { size16, size8, size2, size10 } from "./alloc.js"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
* @param { Num } b
|
||||||
|
*/
|
||||||
|
export function add16(a, b) {
|
||||||
|
let carry = false;
|
||||||
|
const { [kBuffer]: b1 } = a;
|
||||||
|
const { [kBuffer]: b2 } = b;
|
||||||
|
|
||||||
|
for (let i = 0; i < size16; i++) ([b1[i], carry] = add16B(b1[i], b2[i], carry));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
* @param { Num } b
|
||||||
|
*/
|
||||||
|
export function add8(a, b) {
|
||||||
|
let carry = false;
|
||||||
|
const { [kBuffer]: b1 } = a;
|
||||||
|
const { [kBuffer]: b2 } = b;
|
||||||
|
|
||||||
|
for (let i = 0; i < size8; i++) ([b1[i], carry] = add8B(b1[i], b2[i], carry));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
* @param { Num } b
|
||||||
|
*/
|
||||||
|
export function add2(a, b) {
|
||||||
|
let carry = false;
|
||||||
|
const { [kBuffer]: b1 } = a;
|
||||||
|
const { [kBuffer]: b2 } = b;
|
||||||
|
|
||||||
|
for (let i = 0; i < size2; i++) ([b1[i], carry] = add2B(b1[i], b2[i], carry));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
* @param { Num } b
|
||||||
|
*/
|
||||||
|
export function add10(a, b) {
|
||||||
|
let carry = false;
|
||||||
|
const { [kBuffer]: b1 } = a;
|
||||||
|
const { [kBuffer]: b2 } = b;
|
||||||
|
|
||||||
|
for (let i = 0; i < size10; i++) ([b1[i], carry] = add10B(b1[i], b2[i], carry));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
* @param { Num } b
|
||||||
|
*/
|
||||||
|
export function add(a, b) {
|
||||||
|
if (a.radix !== b.radix) throw new Error(`numbers must have same radix`);
|
||||||
|
switch (a.radix) {
|
||||||
|
case 2: return add2(a, b);
|
||||||
|
case 8: return add8(a, b);
|
||||||
|
case 16: return add16(a, b);
|
||||||
|
case 10: return add10(a, b);
|
||||||
|
default: throw new Error(`unsupported radix (${a.radix})`);
|
||||||
|
}
|
||||||
|
}
|
143
lab1/add/10B.js
Normal file
143
lab1/add/10B.js
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
import { S10_0, S10_1, S10_2, S10_3, S10_4, S10_5, S10_6, S10_7, S10_8, S10_9 } from "../symbol/S10.js"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { symbol } a
|
||||||
|
* @param { symbol } b
|
||||||
|
* @param { boolean } carry
|
||||||
|
* @returns { [value: symbol, carry: boolean] }
|
||||||
|
*/
|
||||||
|
export function add10B(a, b, carry) {
|
||||||
|
switch (a) {
|
||||||
|
case S10_0: switch (b) {
|
||||||
|
case S10_0: return carry ? [S10_1, false] : [S10_0, false];
|
||||||
|
case S10_1: return carry ? [S10_2, false] : [S10_1, false];
|
||||||
|
case S10_2: return carry ? [S10_3, false] : [S10_2, false];
|
||||||
|
case S10_3: return carry ? [S10_4, false] : [S10_3, false];
|
||||||
|
case S10_4: return carry ? [S10_5, false] : [S10_4, false];
|
||||||
|
case S10_5: return carry ? [S10_6, false] : [S10_5, false];
|
||||||
|
case S10_6: return carry ? [S10_7, false] : [S10_6, false];
|
||||||
|
case S10_7: return carry ? [S10_8, false] : [S10_7, false];
|
||||||
|
case S10_8: return carry ? [S10_9, false] : [S10_8, false];
|
||||||
|
case S10_9: return carry ? [S10_0, true ] : [S10_9, false];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S10_1: switch (b) {
|
||||||
|
case S10_0: return carry ? [S10_2, false] : [S10_1, false];
|
||||||
|
case S10_1: return carry ? [S10_3, false] : [S10_2, false];
|
||||||
|
case S10_2: return carry ? [S10_4, false] : [S10_3, false];
|
||||||
|
case S10_3: return carry ? [S10_5, false] : [S10_4, false];
|
||||||
|
case S10_4: return carry ? [S10_6, false] : [S10_5, false];
|
||||||
|
case S10_5: return carry ? [S10_7, false] : [S10_6, false];
|
||||||
|
case S10_6: return carry ? [S10_8, false] : [S10_7, false];
|
||||||
|
case S10_7: return carry ? [S10_9, false] : [S10_8, false];
|
||||||
|
case S10_8: return carry ? [S10_0, true ] : [S10_9, false];
|
||||||
|
case S10_9: return carry ? [S10_1, true ] : [S10_0, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S10_2: switch (b) {
|
||||||
|
case S10_0: return carry ? [S10_3, false] : [S10_2, false];
|
||||||
|
case S10_1: return carry ? [S10_4, false] : [S10_3, false];
|
||||||
|
case S10_2: return carry ? [S10_5, false] : [S10_4, false];
|
||||||
|
case S10_3: return carry ? [S10_6, false] : [S10_5, false];
|
||||||
|
case S10_4: return carry ? [S10_7, false] : [S10_6, false];
|
||||||
|
case S10_5: return carry ? [S10_8, false] : [S10_7, false];
|
||||||
|
case S10_6: return carry ? [S10_9, false] : [S10_8, false];
|
||||||
|
case S10_7: return carry ? [S10_0, true ] : [S10_9, false];
|
||||||
|
case S10_8: return carry ? [S10_1, true ] : [S10_0, true ];
|
||||||
|
case S10_9: return carry ? [S10_2, true ] : [S10_1, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S10_3: switch (b) {
|
||||||
|
case S10_0: return carry ? [S10_4, false] : [S10_3, false];
|
||||||
|
case S10_1: return carry ? [S10_5, false] : [S10_4, false];
|
||||||
|
case S10_2: return carry ? [S10_6, false] : [S10_5, false];
|
||||||
|
case S10_3: return carry ? [S10_7, false] : [S10_6, false];
|
||||||
|
case S10_4: return carry ? [S10_8, false] : [S10_7, false];
|
||||||
|
case S10_5: return carry ? [S10_9, false] : [S10_8, false];
|
||||||
|
case S10_6: return carry ? [S10_0, true ] : [S10_9, false];
|
||||||
|
case S10_7: return carry ? [S10_1, true ] : [S10_0, true ];
|
||||||
|
case S10_8: return carry ? [S10_2, true ] : [S10_1, true ];
|
||||||
|
case S10_9: return carry ? [S10_3, true ] : [S10_2, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S10_4: switch (b) {
|
||||||
|
case S10_0: return carry ? [S10_5, false] : [S10_4, false];
|
||||||
|
case S10_1: return carry ? [S10_6, false] : [S10_5, false];
|
||||||
|
case S10_2: return carry ? [S10_7, false] : [S10_6, false];
|
||||||
|
case S10_3: return carry ? [S10_8, false] : [S10_7, false];
|
||||||
|
case S10_4: return carry ? [S10_9, false] : [S10_8, false];
|
||||||
|
case S10_5: return carry ? [S10_0, true ] : [S10_9, false];
|
||||||
|
case S10_6: return carry ? [S10_1, true ] : [S10_0, true ];
|
||||||
|
case S10_7: return carry ? [S10_2, true ] : [S10_1, true ];
|
||||||
|
case S10_8: return carry ? [S10_3, true ] : [S10_2, true ];
|
||||||
|
case S10_9: return carry ? [S10_4, true ] : [S10_3, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S10_5: switch (b) {
|
||||||
|
case S10_0: return carry ? [S10_6, false] : [S10_5, false];
|
||||||
|
case S10_1: return carry ? [S10_7, false] : [S10_6, false];
|
||||||
|
case S10_2: return carry ? [S10_8, false] : [S10_7, false];
|
||||||
|
case S10_3: return carry ? [S10_9, false] : [S10_8, false];
|
||||||
|
case S10_4: return carry ? [S10_0, true ] : [S10_9, false];
|
||||||
|
case S10_5: return carry ? [S10_1, true ] : [S10_0, true ];
|
||||||
|
case S10_6: return carry ? [S10_2, true ] : [S10_1, true ];
|
||||||
|
case S10_7: return carry ? [S10_3, true ] : [S10_2, true ];
|
||||||
|
case S10_8: return carry ? [S10_4, true ] : [S10_3, true ];
|
||||||
|
case S10_9: return carry ? [S10_5, true ] : [S10_4, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S10_6: switch (b) {
|
||||||
|
case S10_0: return carry ? [S10_7, false] : [S10_6, false];
|
||||||
|
case S10_1: return carry ? [S10_8, false] : [S10_7, false];
|
||||||
|
case S10_2: return carry ? [S10_9, false] : [S10_8, false];
|
||||||
|
case S10_3: return carry ? [S10_0, true ] : [S10_9, false];
|
||||||
|
case S10_4: return carry ? [S10_1, true ] : [S10_0, true ];
|
||||||
|
case S10_5: return carry ? [S10_2, true ] : [S10_1, true ];
|
||||||
|
case S10_6: return carry ? [S10_3, true ] : [S10_2, true ];
|
||||||
|
case S10_7: return carry ? [S10_4, true ] : [S10_3, true ];
|
||||||
|
case S10_8: return carry ? [S10_5, true ] : [S10_4, true ];
|
||||||
|
case S10_9: return carry ? [S10_6, true ] : [S10_5, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S10_7: switch (b) {
|
||||||
|
case S10_0: return carry ? [S10_8, false] : [S10_7, false];
|
||||||
|
case S10_1: return carry ? [S10_9, false] : [S10_8, false];
|
||||||
|
case S10_2: return carry ? [S10_0, true ] : [S10_9, false];
|
||||||
|
case S10_3: return carry ? [S10_1, true ] : [S10_0, true ];
|
||||||
|
case S10_4: return carry ? [S10_2, true ] : [S10_1, true ];
|
||||||
|
case S10_5: return carry ? [S10_3, true ] : [S10_2, true ];
|
||||||
|
case S10_6: return carry ? [S10_4, true ] : [S10_3, true ];
|
||||||
|
case S10_7: return carry ? [S10_5, true ] : [S10_4, true ];
|
||||||
|
case S10_8: return carry ? [S10_6, true ] : [S10_5, true ];
|
||||||
|
case S10_9: return carry ? [S10_7, true ] : [S10_6, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S10_8: switch (b) {
|
||||||
|
case S10_0: return carry ? [S10_9, false] : [S10_8, false];
|
||||||
|
case S10_1: return carry ? [S10_0, true ] : [S10_9, false];
|
||||||
|
case S10_2: return carry ? [S10_1, true ] : [S10_0, true ];
|
||||||
|
case S10_3: return carry ? [S10_2, true ] : [S10_1, true ];
|
||||||
|
case S10_4: return carry ? [S10_3, true ] : [S10_2, true ];
|
||||||
|
case S10_5: return carry ? [S10_4, true ] : [S10_3, true ];
|
||||||
|
case S10_6: return carry ? [S10_5, true ] : [S10_4, true ];
|
||||||
|
case S10_7: return carry ? [S10_6, true ] : [S10_5, true ];
|
||||||
|
case S10_8: return carry ? [S10_7, true ] : [S10_6, true ];
|
||||||
|
case S10_9: return carry ? [S10_8, true ] : [S10_7, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S10_9: switch (b) {
|
||||||
|
case S10_0: return carry ? [S10_0, true ] : [S10_9, false];
|
||||||
|
case S10_1: return carry ? [S10_1, true ] : [S10_0, true ];
|
||||||
|
case S10_2: return carry ? [S10_2, true ] : [S10_1, true ];
|
||||||
|
case S10_3: return carry ? [S10_3, true ] : [S10_2, true ];
|
||||||
|
case S10_4: return carry ? [S10_4, true ] : [S10_3, true ];
|
||||||
|
case S10_5: return carry ? [S10_5, true ] : [S10_4, true ];
|
||||||
|
case S10_6: return carry ? [S10_6, true ] : [S10_5, true ];
|
||||||
|
case S10_7: return carry ? [S10_7, true ] : [S10_6, true ];
|
||||||
|
case S10_8: return carry ? [S10_8, true ] : [S10_7, true ];
|
||||||
|
case S10_9: return carry ? [S10_9, true ] : [S10_8, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
317
lab1/add/16B.js
Normal file
317
lab1/add/16B.js
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
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"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { symbol } a
|
||||||
|
* @param { symbol } b
|
||||||
|
* @param { boolean } carry
|
||||||
|
* @returns { [value: symbol, carry: boolean] }
|
||||||
|
*/
|
||||||
|
export function add16B(a, b, carry) {
|
||||||
|
switch (a) {
|
||||||
|
case S16_0: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_1, false] : [S16_0, false];
|
||||||
|
case S16_1: return carry ? [S16_2, false] : [S16_1, false];
|
||||||
|
case S16_2: return carry ? [S16_3, false] : [S16_2, false];
|
||||||
|
case S16_3: return carry ? [S16_4, false] : [S16_3, false];
|
||||||
|
case S16_4: return carry ? [S16_5, false] : [S16_4, false];
|
||||||
|
case S16_5: return carry ? [S16_6, false] : [S16_5, false];
|
||||||
|
case S16_6: return carry ? [S16_7, false] : [S16_6, false];
|
||||||
|
case S16_7: return carry ? [S16_8, false] : [S16_7, false];
|
||||||
|
case S16_8: return carry ? [S16_9, false] : [S16_8, false];
|
||||||
|
case S16_9: return carry ? [S16_A, false] : [S16_9, false];
|
||||||
|
case S16_A: return carry ? [S16_B, false] : [S16_A, false];
|
||||||
|
case S16_B: return carry ? [S16_C, false] : [S16_B, false];
|
||||||
|
case S16_C: return carry ? [S16_D, false] : [S16_C, false];
|
||||||
|
case S16_D: return carry ? [S16_E, false] : [S16_D, false];
|
||||||
|
case S16_E: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_F: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_1: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_2, false] : [S16_1, false];
|
||||||
|
case S16_1: return carry ? [S16_3, false] : [S16_2, false];
|
||||||
|
case S16_2: return carry ? [S16_4, false] : [S16_3, false];
|
||||||
|
case S16_3: return carry ? [S16_5, false] : [S16_4, false];
|
||||||
|
case S16_4: return carry ? [S16_6, false] : [S16_5, false];
|
||||||
|
case S16_5: return carry ? [S16_7, false] : [S16_6, false];
|
||||||
|
case S16_6: return carry ? [S16_8, false] : [S16_7, false];
|
||||||
|
case S16_7: return carry ? [S16_9, false] : [S16_8, false];
|
||||||
|
case S16_8: return carry ? [S16_A, false] : [S16_9, false];
|
||||||
|
case S16_9: return carry ? [S16_B, false] : [S16_A, false];
|
||||||
|
case S16_A: return carry ? [S16_C, false] : [S16_B, false];
|
||||||
|
case S16_B: return carry ? [S16_D, false] : [S16_C, false];
|
||||||
|
case S16_C: return carry ? [S16_E, false] : [S16_D, false];
|
||||||
|
case S16_D: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_E: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_F: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_2: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_3, false] : [S16_2, false];
|
||||||
|
case S16_1: return carry ? [S16_4, false] : [S16_3, false];
|
||||||
|
case S16_2: return carry ? [S16_5, false] : [S16_4, false];
|
||||||
|
case S16_3: return carry ? [S16_6, false] : [S16_5, false];
|
||||||
|
case S16_4: return carry ? [S16_7, false] : [S16_6, false];
|
||||||
|
case S16_5: return carry ? [S16_8, false] : [S16_7, false];
|
||||||
|
case S16_6: return carry ? [S16_9, false] : [S16_8, false];
|
||||||
|
case S16_7: return carry ? [S16_A, false] : [S16_9, false];
|
||||||
|
case S16_8: return carry ? [S16_B, false] : [S16_A, false];
|
||||||
|
case S16_9: return carry ? [S16_C, false] : [S16_B, false];
|
||||||
|
case S16_A: return carry ? [S16_D, false] : [S16_C, false];
|
||||||
|
case S16_B: return carry ? [S16_E, false] : [S16_D, false];
|
||||||
|
case S16_C: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_D: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_E: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
case S16_F: return carry ? [S16_2, true ] : [S16_1, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_3: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_4, false] : [S16_3, false];
|
||||||
|
case S16_1: return carry ? [S16_5, false] : [S16_4, false];
|
||||||
|
case S16_2: return carry ? [S16_6, false] : [S16_5, false];
|
||||||
|
case S16_3: return carry ? [S16_7, false] : [S16_6, false];
|
||||||
|
case S16_4: return carry ? [S16_8, false] : [S16_7, false];
|
||||||
|
case S16_5: return carry ? [S16_9, false] : [S16_8, false];
|
||||||
|
case S16_6: return carry ? [S16_A, false] : [S16_9, false];
|
||||||
|
case S16_7: return carry ? [S16_B, false] : [S16_A, false];
|
||||||
|
case S16_8: return carry ? [S16_C, false] : [S16_B, false];
|
||||||
|
case S16_9: return carry ? [S16_D, false] : [S16_C, false];
|
||||||
|
case S16_A: return carry ? [S16_E, false] : [S16_D, false];
|
||||||
|
case S16_B: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_C: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_D: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
case S16_E: return carry ? [S16_2, true ] : [S16_1, true ];
|
||||||
|
case S16_F: return carry ? [S16_3, true ] : [S16_2, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_4: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_5, false] : [S16_4, false];
|
||||||
|
case S16_1: return carry ? [S16_6, false] : [S16_5, false];
|
||||||
|
case S16_2: return carry ? [S16_7, false] : [S16_6, false];
|
||||||
|
case S16_3: return carry ? [S16_8, false] : [S16_7, false];
|
||||||
|
case S16_4: return carry ? [S16_9, false] : [S16_8, false];
|
||||||
|
case S16_5: return carry ? [S16_A, false] : [S16_9, false];
|
||||||
|
case S16_6: return carry ? [S16_B, false] : [S16_A, false];
|
||||||
|
case S16_7: return carry ? [S16_C, false] : [S16_B, false];
|
||||||
|
case S16_8: return carry ? [S16_D, false] : [S16_C, false];
|
||||||
|
case S16_9: return carry ? [S16_E, false] : [S16_D, false];
|
||||||
|
case S16_A: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_B: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_C: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
case S16_D: return carry ? [S16_2, true ] : [S16_1, true ];
|
||||||
|
case S16_E: return carry ? [S16_3, true ] : [S16_2, true ];
|
||||||
|
case S16_F: return carry ? [S16_4, true ] : [S16_3, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_5: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_6, false] : [S16_5, false];
|
||||||
|
case S16_1: return carry ? [S16_7, false] : [S16_6, false];
|
||||||
|
case S16_2: return carry ? [S16_8, false] : [S16_7, false];
|
||||||
|
case S16_3: return carry ? [S16_9, false] : [S16_8, false];
|
||||||
|
case S16_4: return carry ? [S16_A, false] : [S16_9, false];
|
||||||
|
case S16_5: return carry ? [S16_B, false] : [S16_A, false];
|
||||||
|
case S16_6: return carry ? [S16_C, false] : [S16_B, false];
|
||||||
|
case S16_7: return carry ? [S16_D, false] : [S16_C, false];
|
||||||
|
case S16_8: return carry ? [S16_E, false] : [S16_D, false];
|
||||||
|
case S16_9: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_A: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_B: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
case S16_C: return carry ? [S16_2, true ] : [S16_1, true ];
|
||||||
|
case S16_D: return carry ? [S16_3, true ] : [S16_2, true ];
|
||||||
|
case S16_E: return carry ? [S16_4, true ] : [S16_3, true ];
|
||||||
|
case S16_F: return carry ? [S16_5, true ] : [S16_4, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_6: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_7, false] : [S16_6, false];
|
||||||
|
case S16_1: return carry ? [S16_8, false] : [S16_7, false];
|
||||||
|
case S16_2: return carry ? [S16_9, false] : [S16_8, false];
|
||||||
|
case S16_3: return carry ? [S16_A, false] : [S16_9, false];
|
||||||
|
case S16_4: return carry ? [S16_B, false] : [S16_A, false];
|
||||||
|
case S16_5: return carry ? [S16_C, false] : [S16_B, false];
|
||||||
|
case S16_6: return carry ? [S16_D, false] : [S16_C, false];
|
||||||
|
case S16_7: return carry ? [S16_E, false] : [S16_D, false];
|
||||||
|
case S16_8: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_9: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_A: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
case S16_B: return carry ? [S16_2, true ] : [S16_1, true ];
|
||||||
|
case S16_C: return carry ? [S16_3, true ] : [S16_2, true ];
|
||||||
|
case S16_D: return carry ? [S16_4, true ] : [S16_3, true ];
|
||||||
|
case S16_E: return carry ? [S16_5, true ] : [S16_4, true ];
|
||||||
|
case S16_F: return carry ? [S16_6, true ] : [S16_5, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_7: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_8, false] : [S16_7, false];
|
||||||
|
case S16_1: return carry ? [S16_9, false] : [S16_8, false];
|
||||||
|
case S16_2: return carry ? [S16_A, false] : [S16_9, false];
|
||||||
|
case S16_3: return carry ? [S16_B, false] : [S16_A, false];
|
||||||
|
case S16_4: return carry ? [S16_C, false] : [S16_B, false];
|
||||||
|
case S16_5: return carry ? [S16_D, false] : [S16_C, false];
|
||||||
|
case S16_6: return carry ? [S16_E, false] : [S16_D, false];
|
||||||
|
case S16_7: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_8: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_9: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
case S16_A: return carry ? [S16_2, true ] : [S16_1, true ];
|
||||||
|
case S16_B: return carry ? [S16_3, true ] : [S16_2, true ];
|
||||||
|
case S16_C: return carry ? [S16_4, true ] : [S16_3, true ];
|
||||||
|
case S16_D: return carry ? [S16_5, true ] : [S16_4, true ];
|
||||||
|
case S16_E: return carry ? [S16_6, true ] : [S16_5, true ];
|
||||||
|
case S16_F: return carry ? [S16_7, true ] : [S16_6, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_8: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_9, false] : [S16_8, false];
|
||||||
|
case S16_1: return carry ? [S16_A, false] : [S16_9, false];
|
||||||
|
case S16_2: return carry ? [S16_B, false] : [S16_A, false];
|
||||||
|
case S16_3: return carry ? [S16_C, false] : [S16_B, false];
|
||||||
|
case S16_4: return carry ? [S16_D, false] : [S16_C, false];
|
||||||
|
case S16_5: return carry ? [S16_E, false] : [S16_D, false];
|
||||||
|
case S16_6: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_7: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_8: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
case S16_9: return carry ? [S16_2, true ] : [S16_1, true ];
|
||||||
|
case S16_A: return carry ? [S16_3, true ] : [S16_2, true ];
|
||||||
|
case S16_B: return carry ? [S16_4, true ] : [S16_3, true ];
|
||||||
|
case S16_C: return carry ? [S16_5, true ] : [S16_4, true ];
|
||||||
|
case S16_D: return carry ? [S16_6, true ] : [S16_5, true ];
|
||||||
|
case S16_E: return carry ? [S16_7, true ] : [S16_6, true ];
|
||||||
|
case S16_F: return carry ? [S16_8, true ] : [S16_7, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_9: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_A, false] : [S16_9, false];
|
||||||
|
case S16_1: return carry ? [S16_B, false] : [S16_A, false];
|
||||||
|
case S16_2: return carry ? [S16_C, false] : [S16_B, false];
|
||||||
|
case S16_3: return carry ? [S16_D, false] : [S16_C, false];
|
||||||
|
case S16_4: return carry ? [S16_E, false] : [S16_D, false];
|
||||||
|
case S16_5: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_6: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_7: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
case S16_8: return carry ? [S16_2, true ] : [S16_1, true ];
|
||||||
|
case S16_9: return carry ? [S16_3, true ] : [S16_2, true ];
|
||||||
|
case S16_A: return carry ? [S16_4, true ] : [S16_3, true ];
|
||||||
|
case S16_B: return carry ? [S16_5, true ] : [S16_4, true ];
|
||||||
|
case S16_C: return carry ? [S16_6, true ] : [S16_5, true ];
|
||||||
|
case S16_D: return carry ? [S16_7, true ] : [S16_6, true ];
|
||||||
|
case S16_E: return carry ? [S16_8, true ] : [S16_7, true ];
|
||||||
|
case S16_F: return carry ? [S16_9, true ] : [S16_8, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_A: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_B, false] : [S16_A, false];
|
||||||
|
case S16_1: return carry ? [S16_C, false] : [S16_B, false];
|
||||||
|
case S16_2: return carry ? [S16_D, false] : [S16_C, false];
|
||||||
|
case S16_3: return carry ? [S16_E, false] : [S16_D, false];
|
||||||
|
case S16_4: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_5: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_6: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
case S16_7: return carry ? [S16_2, true ] : [S16_1, true ];
|
||||||
|
case S16_8: return carry ? [S16_3, true ] : [S16_2, true ];
|
||||||
|
case S16_9: return carry ? [S16_4, true ] : [S16_3, true ];
|
||||||
|
case S16_A: return carry ? [S16_5, true ] : [S16_4, true ];
|
||||||
|
case S16_B: return carry ? [S16_6, true ] : [S16_5, true ];
|
||||||
|
case S16_C: return carry ? [S16_7, true ] : [S16_6, true ];
|
||||||
|
case S16_D: return carry ? [S16_8, true ] : [S16_7, true ];
|
||||||
|
case S16_E: return carry ? [S16_9, true ] : [S16_8, true ];
|
||||||
|
case S16_F: return carry ? [S16_A, true ] : [S16_9, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_B: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_C, false] : [S16_B, false];
|
||||||
|
case S16_1: return carry ? [S16_D, false] : [S16_C, false];
|
||||||
|
case S16_2: return carry ? [S16_E, false] : [S16_D, false];
|
||||||
|
case S16_3: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_4: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_5: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
case S16_6: return carry ? [S16_2, true ] : [S16_1, true ];
|
||||||
|
case S16_7: return carry ? [S16_3, true ] : [S16_2, true ];
|
||||||
|
case S16_8: return carry ? [S16_4, true ] : [S16_3, true ];
|
||||||
|
case S16_9: return carry ? [S16_5, true ] : [S16_4, true ];
|
||||||
|
case S16_A: return carry ? [S16_6, true ] : [S16_5, true ];
|
||||||
|
case S16_B: return carry ? [S16_7, true ] : [S16_6, true ];
|
||||||
|
case S16_C: return carry ? [S16_8, true ] : [S16_7, true ];
|
||||||
|
case S16_D: return carry ? [S16_9, true ] : [S16_8, true ];
|
||||||
|
case S16_E: return carry ? [S16_A, true ] : [S16_9, true ];
|
||||||
|
case S16_F: return carry ? [S16_B, true ] : [S16_A, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_C: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_D, false] : [S16_C, false];
|
||||||
|
case S16_1: return carry ? [S16_E, false] : [S16_D, false];
|
||||||
|
case S16_2: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_3: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_4: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
case S16_5: return carry ? [S16_2, true ] : [S16_1, true ];
|
||||||
|
case S16_6: return carry ? [S16_3, true ] : [S16_2, true ];
|
||||||
|
case S16_7: return carry ? [S16_4, true ] : [S16_3, true ];
|
||||||
|
case S16_8: return carry ? [S16_5, true ] : [S16_4, true ];
|
||||||
|
case S16_9: return carry ? [S16_6, true ] : [S16_5, true ];
|
||||||
|
case S16_A: return carry ? [S16_7, true ] : [S16_6, true ];
|
||||||
|
case S16_B: return carry ? [S16_8, true ] : [S16_7, true ];
|
||||||
|
case S16_C: return carry ? [S16_9, true ] : [S16_8, true ];
|
||||||
|
case S16_D: return carry ? [S16_A, true ] : [S16_9, true ];
|
||||||
|
case S16_E: return carry ? [S16_B, true ] : [S16_A, true ];
|
||||||
|
case S16_F: return carry ? [S16_C, true ] : [S16_B, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_D: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_E, false] : [S16_D, false];
|
||||||
|
case S16_1: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_2: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_3: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
case S16_4: return carry ? [S16_2, true ] : [S16_1, true ];
|
||||||
|
case S16_5: return carry ? [S16_3, true ] : [S16_2, true ];
|
||||||
|
case S16_6: return carry ? [S16_4, true ] : [S16_3, true ];
|
||||||
|
case S16_7: return carry ? [S16_5, true ] : [S16_4, true ];
|
||||||
|
case S16_8: return carry ? [S16_6, true ] : [S16_5, true ];
|
||||||
|
case S16_9: return carry ? [S16_7, true ] : [S16_6, true ];
|
||||||
|
case S16_A: return carry ? [S16_8, true ] : [S16_7, true ];
|
||||||
|
case S16_B: return carry ? [S16_9, true ] : [S16_8, true ];
|
||||||
|
case S16_C: return carry ? [S16_A, true ] : [S16_9, true ];
|
||||||
|
case S16_D: return carry ? [S16_B, true ] : [S16_A, true ];
|
||||||
|
case S16_E: return carry ? [S16_C, true ] : [S16_B, true ];
|
||||||
|
case S16_F: return carry ? [S16_D, true ] : [S16_C, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_E: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_F, false] : [S16_E, false];
|
||||||
|
case S16_1: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_2: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
case S16_3: return carry ? [S16_2, true ] : [S16_1, true ];
|
||||||
|
case S16_4: return carry ? [S16_3, true ] : [S16_2, true ];
|
||||||
|
case S16_5: return carry ? [S16_4, true ] : [S16_3, true ];
|
||||||
|
case S16_6: return carry ? [S16_5, true ] : [S16_4, true ];
|
||||||
|
case S16_7: return carry ? [S16_6, true ] : [S16_5, true ];
|
||||||
|
case S16_8: return carry ? [S16_7, true ] : [S16_6, true ];
|
||||||
|
case S16_9: return carry ? [S16_8, true ] : [S16_7, true ];
|
||||||
|
case S16_A: return carry ? [S16_9, true ] : [S16_8, true ];
|
||||||
|
case S16_B: return carry ? [S16_A, true ] : [S16_9, true ];
|
||||||
|
case S16_C: return carry ? [S16_B, true ] : [S16_A, true ];
|
||||||
|
case S16_D: return carry ? [S16_C, true ] : [S16_B, true ];
|
||||||
|
case S16_E: return carry ? [S16_D, true ] : [S16_C, true ];
|
||||||
|
case S16_F: return carry ? [S16_E, true ] : [S16_D, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S16_F: switch (b) {
|
||||||
|
case S16_0: return carry ? [S16_0, true ] : [S16_F, false];
|
||||||
|
case S16_1: return carry ? [S16_1, true ] : [S16_0, true ];
|
||||||
|
case S16_2: return carry ? [S16_2, true ] : [S16_1, true ];
|
||||||
|
case S16_3: return carry ? [S16_3, true ] : [S16_2, true ];
|
||||||
|
case S16_4: return carry ? [S16_4, true ] : [S16_3, true ];
|
||||||
|
case S16_5: return carry ? [S16_5, true ] : [S16_4, true ];
|
||||||
|
case S16_6: return carry ? [S16_6, true ] : [S16_5, true ];
|
||||||
|
case S16_7: return carry ? [S16_7, true ] : [S16_6, true ];
|
||||||
|
case S16_8: return carry ? [S16_8, true ] : [S16_7, true ];
|
||||||
|
case S16_9: return carry ? [S16_9, true ] : [S16_8, true ];
|
||||||
|
case S16_A: return carry ? [S16_A, true ] : [S16_9, true ];
|
||||||
|
case S16_B: return carry ? [S16_B, true ] : [S16_A, true ];
|
||||||
|
case S16_C: return carry ? [S16_C, true ] : [S16_B, true ];
|
||||||
|
case S16_D: return carry ? [S16_D, true ] : [S16_C, true ];
|
||||||
|
case S16_E: return carry ? [S16_E, true ] : [S16_D, true ];
|
||||||
|
case S16_F: return carry ? [S16_F, true ] : [S16_E, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
23
lab1/add/2B.js
Normal file
23
lab1/add/2B.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { S2_0, S2_1 } from "../symbol/S2.js"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { symbol } a
|
||||||
|
* @param { symbol } b
|
||||||
|
* @param { boolean } carry
|
||||||
|
* @returns { [value: symbol, carry: boolean] }
|
||||||
|
*/
|
||||||
|
export function add2B(a, b, carry) {
|
||||||
|
switch (a) {
|
||||||
|
case S2_0: switch (b) {
|
||||||
|
case S2_0: return carry ? [S2_1, false] : [S2_0, false];
|
||||||
|
case S2_1: return carry ? [S2_0, true ] : [S2_1, false];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S2_1: switch (b) {
|
||||||
|
case S2_0: return carry ? [S2_0, true] : [S2_1, false];
|
||||||
|
case S2_1: return carry ? [S2_1, true] : [S2_0, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
102
lab1/add/8B.js
Normal file
102
lab1/add/8B.js
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import { S8_0, S8_1, S8_2, S8_3, S8_4, S8_5, S8_6, S8_7 } from "../symbol/S8.js"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { symbol } a
|
||||||
|
* @param { symbol } b
|
||||||
|
* @param { boolean } carry
|
||||||
|
* @returns { [value: symbol, carry: boolean] }
|
||||||
|
*/
|
||||||
|
export function add8B(a, b, carry) {
|
||||||
|
switch (a) {
|
||||||
|
case S8_0: switch (b) {
|
||||||
|
case S8_0: return carry ? [S8_1, false] : [S8_0, false];
|
||||||
|
case S8_1: return carry ? [S8_2, false] : [S8_1, false];
|
||||||
|
case S8_2: return carry ? [S8_3, false] : [S8_2, false];
|
||||||
|
case S8_3: return carry ? [S8_4, false] : [S8_3, false];
|
||||||
|
case S8_4: return carry ? [S8_5, false] : [S8_4, false];
|
||||||
|
case S8_5: return carry ? [S8_6, false] : [S8_5, false];
|
||||||
|
case S8_6: return carry ? [S8_7, false] : [S8_6, false];
|
||||||
|
case S8_7: return carry ? [S8_0, true ] : [S8_7, false];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S8_1: switch (b) {
|
||||||
|
case S8_0: return carry ? [S8_2, false] : [S8_1, false];
|
||||||
|
case S8_1: return carry ? [S8_3, false] : [S8_2, false];
|
||||||
|
case S8_2: return carry ? [S8_4, false] : [S8_3, false];
|
||||||
|
case S8_3: return carry ? [S8_5, false] : [S8_4, false];
|
||||||
|
case S8_4: return carry ? [S8_6, false] : [S8_5, false];
|
||||||
|
case S8_5: return carry ? [S8_7, false] : [S8_6, false];
|
||||||
|
case S8_6: return carry ? [S8_0, true ] : [S8_7, false];
|
||||||
|
case S8_7: return carry ? [S8_1, true ] : [S8_0, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S8_2: switch (b) {
|
||||||
|
case S8_0: return carry ? [S8_3, false] : [S8_2, false];
|
||||||
|
case S8_1: return carry ? [S8_4, false] : [S8_3, false];
|
||||||
|
case S8_2: return carry ? [S8_5, false] : [S8_4, false];
|
||||||
|
case S8_3: return carry ? [S8_6, false] : [S8_5, false];
|
||||||
|
case S8_4: return carry ? [S8_7, false] : [S8_6, false];
|
||||||
|
case S8_5: return carry ? [S8_0, true ] : [S8_7, false];
|
||||||
|
case S8_6: return carry ? [S8_1, true ] : [S8_0, true ];
|
||||||
|
case S8_7: return carry ? [S8_2, true ] : [S8_1, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S8_3: switch (b) {
|
||||||
|
case S8_0: return carry ? [S8_4, false] : [S8_3, false];
|
||||||
|
case S8_1: return carry ? [S8_5, false] : [S8_4, false];
|
||||||
|
case S8_2: return carry ? [S8_6, false] : [S8_5, false];
|
||||||
|
case S8_3: return carry ? [S8_7, false] : [S8_6, false];
|
||||||
|
case S8_4: return carry ? [S8_0, true ] : [S8_7, false];
|
||||||
|
case S8_5: return carry ? [S8_1, true ] : [S8_0, true ];
|
||||||
|
case S8_6: return carry ? [S8_2, true ] : [S8_1, true ];
|
||||||
|
case S8_7: return carry ? [S8_3, true ] : [S8_2, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S8_4: switch (b) {
|
||||||
|
case S8_0: return carry ? [S8_5, false] : [S8_4, false];
|
||||||
|
case S8_1: return carry ? [S8_6, false] : [S8_5, false];
|
||||||
|
case S8_2: return carry ? [S8_7, false] : [S8_6, false];
|
||||||
|
case S8_3: return carry ? [S8_0, true ] : [S8_7, false];
|
||||||
|
case S8_4: return carry ? [S8_1, true ] : [S8_0, true ];
|
||||||
|
case S8_5: return carry ? [S8_2, true ] : [S8_1, true ];
|
||||||
|
case S8_6: return carry ? [S8_3, true ] : [S8_2, true ];
|
||||||
|
case S8_7: return carry ? [S8_4, true ] : [S8_3, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S8_5: switch (b) {
|
||||||
|
case S8_0: return carry ? [S8_6, false] : [S8_5, false];
|
||||||
|
case S8_1: return carry ? [S8_7, false] : [S8_6, false];
|
||||||
|
case S8_2: return carry ? [S8_0, true ] : [S8_7, false];
|
||||||
|
case S8_3: return carry ? [S8_1, true ] : [S8_0, true ];
|
||||||
|
case S8_4: return carry ? [S8_2, true ] : [S8_1, true ];
|
||||||
|
case S8_5: return carry ? [S8_3, true ] : [S8_2, true ];
|
||||||
|
case S8_6: return carry ? [S8_4, true ] : [S8_3, true ];
|
||||||
|
case S8_7: return carry ? [S8_5, true ] : [S8_4, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S8_6: switch (b) {
|
||||||
|
case S8_0: return carry ? [S8_7, false] : [S8_6, false];
|
||||||
|
case S8_1: return carry ? [S8_0, true ] : [S8_7, false];
|
||||||
|
case S8_2: return carry ? [S8_1, true ] : [S8_0, true ];
|
||||||
|
case S8_3: return carry ? [S8_2, true ] : [S8_1, true ];
|
||||||
|
case S8_4: return carry ? [S8_3, true ] : [S8_2, true ];
|
||||||
|
case S8_5: return carry ? [S8_4, true ] : [S8_3, true ];
|
||||||
|
case S8_6: return carry ? [S8_5, true ] : [S8_4, true ];
|
||||||
|
case S8_7: return carry ? [S8_6, true ] : [S8_5, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
case S8_7: switch (b) {
|
||||||
|
case S8_0: return carry ? [S8_0, true ] : [S8_7, false];
|
||||||
|
case S8_1: return carry ? [S8_1, true ] : [S8_0, true ];
|
||||||
|
case S8_2: return carry ? [S8_2, true ] : [S8_1, true ];
|
||||||
|
case S8_3: return carry ? [S8_3, true ] : [S8_2, true ];
|
||||||
|
case S8_4: return carry ? [S8_4, true ] : [S8_3, true ];
|
||||||
|
case S8_5: return carry ? [S8_5, true ] : [S8_4, true ];
|
||||||
|
case S8_6: return carry ? [S8_6, true ] : [S8_5, true ];
|
||||||
|
case S8_7: return carry ? [S8_7, true ] : [S8_6, true ];
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
106
lab1/alloc.js
Normal file
106
lab1/alloc.js
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/**
|
||||||
|
* @import { Radix } from "./num.js"
|
||||||
|
*/
|
||||||
|
import { S16_0 } from "./symbol/S16.js"
|
||||||
|
import { S8_0 } from "./symbol/S8.js"
|
||||||
|
import { S2_0 } from "./symbol/S2.js"
|
||||||
|
import { S10_0 } from "./symbol/S10.js"
|
||||||
|
|
||||||
|
function alloc16() {
|
||||||
|
return [
|
||||||
|
S16_0,
|
||||||
|
S16_0,
|
||||||
|
S16_0,
|
||||||
|
S16_0,
|
||||||
|
S16_0,
|
||||||
|
S16_0,
|
||||||
|
S16_0,
|
||||||
|
S16_0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
export const size16 = 8;
|
||||||
|
|
||||||
|
function alloc8() {
|
||||||
|
return [
|
||||||
|
S8_0,
|
||||||
|
S8_0,
|
||||||
|
S8_0,
|
||||||
|
S8_0,
|
||||||
|
S8_0,
|
||||||
|
S8_0,
|
||||||
|
S8_0,
|
||||||
|
S8_0,
|
||||||
|
S8_0,
|
||||||
|
S8_0,
|
||||||
|
S8_0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
export const size8 = 11;
|
||||||
|
|
||||||
|
function alloc2() {
|
||||||
|
return [
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0,
|
||||||
|
S2_0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
export const size2 = 32;
|
||||||
|
|
||||||
|
function alloc10() {
|
||||||
|
return [
|
||||||
|
S10_0,
|
||||||
|
S10_0,
|
||||||
|
S10_0,
|
||||||
|
S10_0,
|
||||||
|
S10_0,
|
||||||
|
S10_0,
|
||||||
|
S10_0,
|
||||||
|
S10_0,
|
||||||
|
S10_0,
|
||||||
|
S10_0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
export const size10 = 10;
|
||||||
|
export const last10 = size10 - 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Radix } radix
|
||||||
|
*/
|
||||||
|
export function alloc(radix) {
|
||||||
|
switch (radix) {
|
||||||
|
case 2: return alloc2();
|
||||||
|
case 8: return alloc8();
|
||||||
|
case 16: return alloc16();
|
||||||
|
case 10: return alloc10();
|
||||||
|
default: throw new Error(`unsupported radix (${radix})`);
|
||||||
|
}
|
||||||
|
}
|
403
lab1/convert.js
Normal file
403
lab1/convert.js
Normal file
@ -0,0 +1,403 @@
|
|||||||
|
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;
|
||||||
|
}
|
34
lab1/convert.test.js
Normal file
34
lab1/convert.test.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { Num } from "./index.js"
|
||||||
|
|
||||||
|
for (let i = 0; i < 0xFFFF; i++) {
|
||||||
|
const str2 = `0b${i.toString(2).toUpperCase()}`;
|
||||||
|
const str8 = `0o${i.toString(8).toUpperCase()}`;
|
||||||
|
const str16 = `0x${i.toString(16).toUpperCase()}`;
|
||||||
|
const str10 = i.toString(10).toUpperCase();
|
||||||
|
|
||||||
|
const t2 = Num.parse(str2);
|
||||||
|
const t8 = Num.parse(str8);
|
||||||
|
const t16 = Num.parse(str16);
|
||||||
|
const t10 = Num.parse(str10);
|
||||||
|
|
||||||
|
if (t2.as(2).toString() !== str2) throw new Error(`${str2}:${t2.as(2).toString()}`);
|
||||||
|
if (t2.as(8).toString() !== str8) throw new Error(`${str2}:${t2.as(8).toString()}`);
|
||||||
|
if (t2.as(16).toString() !== str16) throw new Error(`${str2}:${t2.as(16).toString()}`);
|
||||||
|
if (t2.as(10).toString() !== str10) throw new Error(`${str2}:${t2.as(10).toString()}`);
|
||||||
|
|
||||||
|
if (t8.as(2).toString() !== str2) throw new Error(`${str2}:${t8.as(2).toString()}`);
|
||||||
|
if (t8.as(8).toString() !== str8) throw new Error(`${str2}:${t8.as(8).toString()}`);
|
||||||
|
if (t8.as(16).toString() !== str16) throw new Error(`${str2}:${t8.as(16).toString()}`);
|
||||||
|
if (t8.as(10).toString() !== str10) throw new Error(`${str2}:${t8.as(10).toString()}`);
|
||||||
|
|
||||||
|
if (t16.as(2).toString() !== str2) throw new Error(`${str2}:${t16.as(2).toString()}`);
|
||||||
|
if (t16.as(8).toString() !== str8) throw new Error(`${str2}:${t16.as(8).toString()}`);
|
||||||
|
if (t16.as(16).toString() !== str16) throw new Error(`${str2}:${t16.as(16).toString()}`);
|
||||||
|
if (t16.as(10).toString() !== str10) throw new Error(`${str2}:${t16.as(10).toString()}`);
|
||||||
|
|
||||||
|
if (t10.as(2).toString() !== str2) throw new Error(`${str2}:${t10.as(2).toString()}`);
|
||||||
|
if (t10.as(8).toString() !== str8) throw new Error(`${str2}:${t10.as(8).toString()}`);
|
||||||
|
if (t10.as(16).toString() !== str16) throw new Error(`${str2}:${t10.as(16).toString()}`);
|
||||||
|
if (t10.as(10).toString() !== str10) throw new Error(`${str2}:${t10.as(10).toString()}`);
|
||||||
|
|
||||||
|
}
|
41
lab1/demo.js
Normal file
41
lab1/demo.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { Num, add, sub } from "./index.js";
|
||||||
|
|
||||||
|
const A = 123123;
|
||||||
|
const B = 879;
|
||||||
|
|
||||||
|
const a = Num.parse(A.toString());
|
||||||
|
const b = Num.parse(B.toString());
|
||||||
|
|
||||||
|
/**@type { { expression: string; correct: boolean; }[] } */
|
||||||
|
const results = [];
|
||||||
|
|
||||||
|
for (const radix of /**@type { const } */([10, 2, 8, 16])) {
|
||||||
|
const a1 = a.as(radix);
|
||||||
|
const b1 = b.as(radix);
|
||||||
|
// console.log(`a { radix: ${radix} } ${ a1.toString() } (${ Number(a1.toString()) == A })`);
|
||||||
|
results.push({
|
||||||
|
expression: `a { radix: ${radix} } ${ a1.toString() }`,
|
||||||
|
correct: Number(a1.toString()) == A
|
||||||
|
});
|
||||||
|
// console.log(`b { radix: ${radix} } ${ b1.toString() } (${ Number(b1.toString()) == B })`);
|
||||||
|
results.push({
|
||||||
|
expression: `b { radix: ${radix} } ${ b1.toString() }`,
|
||||||
|
correct: Number(b1.toString()) == B
|
||||||
|
});
|
||||||
|
const a2 = a1.copy()
|
||||||
|
const a3 = a1.copy();
|
||||||
|
add(a2, b1);
|
||||||
|
sub(a3, b1);
|
||||||
|
// console.log(`a + b = ${ a2.toString() } (${ Number(a2.toString()) == (A + B) })`);
|
||||||
|
results.push({
|
||||||
|
expression: `a + b = ${ a2.toString() }`,
|
||||||
|
correct: Number(a2.toString()) == (A + B)
|
||||||
|
});
|
||||||
|
// console.log(`a - b = ${ a3.toString() } (${ Number(a3.toString()) == (A - B) })`);
|
||||||
|
results.push({
|
||||||
|
expression: `a - b = ${ a3.toString() }`,
|
||||||
|
correct: Number(a3.toString()) == (A - B)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.table(results);
|
4
lab1/index.js
Normal file
4
lab1/index.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export { add } from "./add.js"
|
||||||
|
export { sub } from "./sub.js"
|
||||||
|
export { not } from "./not.js"
|
||||||
|
export { Num } from "./num.js"
|
27
lab1/math.test.js
Normal file
27
lab1/math.test.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* @import { Radix } from "./num.js"
|
||||||
|
*/
|
||||||
|
import { Num, add, sub } from "./index.js"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { number } number
|
||||||
|
* @param { number } radix
|
||||||
|
* @param { string } prefix
|
||||||
|
*/
|
||||||
|
function stringify(number, radix, prefix) {
|
||||||
|
return (Math.sign(number) === -1 ? "-" : "") + prefix + Math.abs(number).toString(radix).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [radix, prefix] of /**@type { [radix: Radix, prefix: string][]}*/([[2, "0b"], [8, "0o"], [16, "0x"], [10, ""]])) {
|
||||||
|
for (let i = 0; i < 0xFFF; i++) {
|
||||||
|
for (let j = 0; j < 0xFFF; j++) {
|
||||||
|
const a1 = Num.parse(`${prefix}${i.toString(radix)}`);
|
||||||
|
const a2 = a1.copy();
|
||||||
|
const b = Num.parse(`${prefix}${j.toString(radix)}`);
|
||||||
|
add(a1, b);
|
||||||
|
sub(a2, b);
|
||||||
|
console.assert(a1.toString() === stringify(i + j, radix, prefix), i, j, stringify(i + j, radix, prefix), a1.toString());
|
||||||
|
console.assert(a2.toString() === stringify(i - j, radix, prefix), i, j, stringify(i - j, radix, prefix), a2.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
102
lab1/neg.js
Normal file
102
lab1/neg.js
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/**
|
||||||
|
* @import { Num } from "./num.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"
|
||||||
|
import { S2_0, S2_1 } from "./symbol/S2.js"
|
||||||
|
import { S10_0, S10_1, S10_2, S10_3, S10_4, S10_5, S10_6, S10_7, S10_8, S10_9 } from "./symbol/S10.js"
|
||||||
|
|
||||||
|
import { kBuffer } from "./num.js"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
*/
|
||||||
|
function neg16(a) {
|
||||||
|
const { [kBuffer]: buff } = a;
|
||||||
|
switch (buff[buff.length - 1]) {
|
||||||
|
case S16_0: return false;
|
||||||
|
case S16_1: return false;
|
||||||
|
case S16_2: return false;
|
||||||
|
case S16_3: return false;
|
||||||
|
case S16_4: return false;
|
||||||
|
case S16_5: return false;
|
||||||
|
case S16_6: return false;
|
||||||
|
case S16_7: return false;
|
||||||
|
|
||||||
|
case S16_8: return true;
|
||||||
|
case S16_9: return true;
|
||||||
|
case S16_A: return true;
|
||||||
|
case S16_B: return true;
|
||||||
|
case S16_C: return true;
|
||||||
|
case S16_D: return true;
|
||||||
|
case S16_E: return true;
|
||||||
|
case S16_F: return true;
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
*/
|
||||||
|
function neg8(a) {
|
||||||
|
const { [kBuffer]: buff } = a;
|
||||||
|
switch (buff[buff.length - 1]) {
|
||||||
|
case S8_0: return false;
|
||||||
|
case S8_1: return false;
|
||||||
|
case S8_2: return false;
|
||||||
|
case S8_3: return false;
|
||||||
|
|
||||||
|
case S8_4: return true;
|
||||||
|
case S8_5: return true;
|
||||||
|
case S8_6: return true;
|
||||||
|
case S8_7: return true;
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
*/
|
||||||
|
function neg2(a) {
|
||||||
|
const { [kBuffer]: buff } = a;
|
||||||
|
switch (buff[buff.length - 1]) {
|
||||||
|
case S2_0: return false;
|
||||||
|
|
||||||
|
case S2_1: return true;
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
*/
|
||||||
|
function neg10(a) {
|
||||||
|
const { [kBuffer]: buff } = a;
|
||||||
|
switch (buff[buff.length - 1]) {
|
||||||
|
case S10_0: return false;
|
||||||
|
case S10_1: return false;
|
||||||
|
case S10_2: return false;
|
||||||
|
case S10_3: return false;
|
||||||
|
case S10_4: return false;
|
||||||
|
|
||||||
|
case S10_5: return true;
|
||||||
|
case S10_6: return true;
|
||||||
|
case S10_7: return true;
|
||||||
|
case S10_8: return true;
|
||||||
|
case S10_9: return true;
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
*/
|
||||||
|
export function neg(a) {
|
||||||
|
switch (a.radix) {
|
||||||
|
case 2: return neg2(a);
|
||||||
|
case 8: return neg8(a);
|
||||||
|
case 16: return neg16(a);
|
||||||
|
case 10: return neg10(a);
|
||||||
|
default: throw new Error(`unsupported radix (${a.radix})`);
|
||||||
|
}
|
||||||
|
}
|
137
lab1/not.js
Normal file
137
lab1/not.js
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
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"
|
||||||
|
import { S2_0, S2_1 } from "./symbol/S2.js"
|
||||||
|
import { S10_0, S10_1, S10_2, S10_3, S10_4, S10_5, S10_6, S10_7, S10_8, S10_9 } from "./symbol/S10.js"
|
||||||
|
import { kBuffer, Num } from "./num.js"
|
||||||
|
import { add16, add8, add2, add10 } from "./add.js"
|
||||||
|
import { size16, size8, size2, size10 } from "./alloc.js"
|
||||||
|
import { one10, one16, one2, one8 } from "./num.js"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { symbol } a
|
||||||
|
*/
|
||||||
|
function not16B(a) {
|
||||||
|
switch (a) {
|
||||||
|
case S16_0: return S16_F;
|
||||||
|
case S16_1: return S16_E;
|
||||||
|
case S16_2: return S16_D;
|
||||||
|
case S16_3: return S16_C;
|
||||||
|
case S16_4: return S16_B;
|
||||||
|
case S16_5: return S16_A;
|
||||||
|
case S16_6: return S16_9;
|
||||||
|
case S16_7: return S16_8;
|
||||||
|
case S16_8: return S16_7;
|
||||||
|
case S16_9: return S16_6;
|
||||||
|
case S16_A: return S16_5;
|
||||||
|
case S16_B: return S16_4;
|
||||||
|
case S16_C: return S16_3;
|
||||||
|
case S16_D: return S16_2;
|
||||||
|
case S16_E: return S16_1;
|
||||||
|
case S16_F: return S16_0;
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { symbol } a
|
||||||
|
*/
|
||||||
|
function not8B(a) {
|
||||||
|
switch (a) {
|
||||||
|
case S8_0: return S8_7;
|
||||||
|
case S8_1: return S8_6;
|
||||||
|
case S8_2: return S8_5;
|
||||||
|
case S8_3: return S8_4;
|
||||||
|
case S8_4: return S8_3;
|
||||||
|
case S8_5: return S8_2;
|
||||||
|
case S8_6: return S8_1;
|
||||||
|
case S8_7: return S8_0;
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { symbol } a
|
||||||
|
*/
|
||||||
|
function not2B(a) {
|
||||||
|
switch (a) {
|
||||||
|
case S2_0: return S2_1;
|
||||||
|
case S2_1: return S2_0;
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { symbol } a
|
||||||
|
*/
|
||||||
|
function not10B(a) {
|
||||||
|
switch (a) {
|
||||||
|
case S10_0: return S10_9;
|
||||||
|
case S10_1: return S10_8;
|
||||||
|
case S10_2: return S10_7;
|
||||||
|
case S10_3: return S10_6;
|
||||||
|
case S10_4: return S10_5;
|
||||||
|
case S10_5: return S10_4;
|
||||||
|
case S10_6: return S10_3;
|
||||||
|
case S10_7: return S10_2;
|
||||||
|
case S10_8: return S10_1;
|
||||||
|
case S10_9: return S10_0;
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
*/
|
||||||
|
export function not16(a) {
|
||||||
|
const { [kBuffer]: buff } = a;
|
||||||
|
for (let i = 0; i < size16; i++) {
|
||||||
|
buff[i] = not16B(buff[i]);
|
||||||
|
}
|
||||||
|
add16(a, one16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
*/
|
||||||
|
export function not8(a) {
|
||||||
|
const { [kBuffer]: buff } = a;
|
||||||
|
for (let i = 0; i < size8; i++) {
|
||||||
|
buff[i] = not8B(buff[i]);
|
||||||
|
}
|
||||||
|
add8(a, one8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
*/
|
||||||
|
export function not2(a) {
|
||||||
|
const { [kBuffer]: buff } = a;
|
||||||
|
for (let i = 0; i < size2; i++) {
|
||||||
|
buff[i] = not2B(buff[i]);
|
||||||
|
}
|
||||||
|
add2(a, one2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
*/
|
||||||
|
export function not10(a) {
|
||||||
|
const { [kBuffer]: buff } = a;
|
||||||
|
for (let i = 0; i < size10; i++) {
|
||||||
|
buff[i] = not10B(buff[i]);
|
||||||
|
}
|
||||||
|
add10(a, one10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
*/
|
||||||
|
export function not(a) {
|
||||||
|
switch (a.radix) {
|
||||||
|
case 2: return not2(a);
|
||||||
|
case 8: return not8(a);
|
||||||
|
case 16: return not16(a);
|
||||||
|
case 10: return not10(a);
|
||||||
|
default: throw new Error(`unsupported radix (${a.radix})`);
|
||||||
|
}
|
||||||
|
}
|
195
lab1/num.js
Normal file
195
lab1/num.js
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
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);
|
3
lab1/package.json
Normal file
3
lab1/package.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"type": "module"
|
||||||
|
}
|
141
lab1/parse.js
Normal file
141
lab1/parse.js
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/**
|
||||||
|
* @import { Radix } from "./num.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"
|
||||||
|
import { S2_0, S2_1 } from "./symbol/S2.js"
|
||||||
|
import { S10_0, S10_1, S10_2, S10_3, S10_4, S10_5, S10_6, S10_7, S10_8, S10_9 } from "./symbol/S10.js"
|
||||||
|
import { __throw } from "./utils.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { string } char
|
||||||
|
*/
|
||||||
|
function parse16B(char) {
|
||||||
|
switch (char) {
|
||||||
|
case "0": return S16_0;
|
||||||
|
case "1": return S16_1;
|
||||||
|
case "2": return S16_2;
|
||||||
|
case "3": return S16_3;
|
||||||
|
case "4": return S16_4;
|
||||||
|
case "5": return S16_5;
|
||||||
|
case "6": return S16_6;
|
||||||
|
case "7": return S16_7;
|
||||||
|
case "8": return S16_8;
|
||||||
|
case "9": return S16_9;
|
||||||
|
case "a": return S16_A;
|
||||||
|
case "A": return S16_A;
|
||||||
|
case "b": return S16_B;
|
||||||
|
case "B": return S16_B;
|
||||||
|
case "c": return S16_C;
|
||||||
|
case "C": return S16_C;
|
||||||
|
case "d": return S16_D;
|
||||||
|
case "D": return S16_D;
|
||||||
|
case "e": return S16_E;
|
||||||
|
case "E": return S16_E;
|
||||||
|
case "f": return S16_F;
|
||||||
|
case "F": return S16_F;
|
||||||
|
default: throw new Error(`unexpected symbol (${char})`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { string } char
|
||||||
|
*/
|
||||||
|
function parse8B(char) {
|
||||||
|
switch (char) {
|
||||||
|
case "0": return S8_0;
|
||||||
|
case "1": return S8_1;
|
||||||
|
case "2": return S8_2;
|
||||||
|
case "3": return S8_3;
|
||||||
|
case "4": return S8_4;
|
||||||
|
case "5": return S8_5;
|
||||||
|
case "6": return S8_6;
|
||||||
|
case "7": return S8_7;
|
||||||
|
default: throw new Error(`unexpected symbol (${char})`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { string } char
|
||||||
|
*/
|
||||||
|
function parse2B(char) {
|
||||||
|
switch (char) {
|
||||||
|
case "0": return S2_0;
|
||||||
|
case "1": return S2_1;
|
||||||
|
default: throw new Error(`unexpected symbol (${char})`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { string } char
|
||||||
|
*/
|
||||||
|
function parse10B(char) {
|
||||||
|
switch (char) {
|
||||||
|
case "0": return S10_0;
|
||||||
|
case "1": return S10_1;
|
||||||
|
case "2": return S10_2;
|
||||||
|
case "3": return S10_3;
|
||||||
|
case "4": return S10_4;
|
||||||
|
case "5": return S10_5;
|
||||||
|
case "6": return S10_6;
|
||||||
|
case "7": return S10_7;
|
||||||
|
case "8": return S10_8;
|
||||||
|
case "9": return S10_9;
|
||||||
|
default: throw new Error(`unexpected symbol (${char})`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { string } value
|
||||||
|
* @param { symbol[] } buffer
|
||||||
|
*/
|
||||||
|
function parse16(value, buffer) {
|
||||||
|
for (let i = 0, j = value.length - 1; i < buffer.length && j >= 0; i++, j--) {
|
||||||
|
buffer[i] = parse16B(value[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { string } value
|
||||||
|
* @param { symbol[] } buffer
|
||||||
|
*/
|
||||||
|
function parse8(value, buffer) {
|
||||||
|
for (let i = 0, j = value.length - 1; i < buffer.length && j >= 0; i++, j--) {
|
||||||
|
buffer[i] = parse8B(value[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { string } value
|
||||||
|
* @param { symbol[] } buffer
|
||||||
|
*/
|
||||||
|
function parse2(value, buffer) {
|
||||||
|
for (let i = 0, j = value.length - 1; i < buffer.length && j >= 0; i++, j--) {
|
||||||
|
buffer[i] = parse2B(value[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { string } value
|
||||||
|
* @param { symbol[] } buffer
|
||||||
|
*/
|
||||||
|
function parse10(value, buffer) {
|
||||||
|
for (let i = 0, j = value.length - 1; i < buffer.length && j >= 0; i++, j--) {
|
||||||
|
buffer[i] = parse10B(value[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Radix } radix
|
||||||
|
* @param { string } value
|
||||||
|
* @param { symbol[] } buffer
|
||||||
|
*/
|
||||||
|
export function parse(radix, value, buffer) {
|
||||||
|
switch (radix) {
|
||||||
|
case 2: return parse2(value, buffer);
|
||||||
|
case 8: return parse8(value, buffer);
|
||||||
|
case 16: return parse16(value, buffer);
|
||||||
|
case 10: return parse10(value, buffer);
|
||||||
|
default: throw new Error(`unsupported radix (${radix})`);
|
||||||
|
}
|
||||||
|
}
|
65
lab1/string.js
Normal file
65
lab1/string.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
* @import { Num } from "./num.js"
|
||||||
|
*/
|
||||||
|
import { kBuffer } from "./num.js";
|
||||||
|
import { string16B } from "./string/16B.js"
|
||||||
|
import { string8B } from "./string/8B.js"
|
||||||
|
import { string2B } from "./string/2B.js";
|
||||||
|
import { string10B } from "./string/10B.js"
|
||||||
|
import { S8_0 } from "./symbol/S8.js";
|
||||||
|
import { S16_0 } from "./symbol/S16.js";
|
||||||
|
import { S2_0 } from "./symbol/S2.js";
|
||||||
|
import { S10_0 } from "./symbol/S10.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } n
|
||||||
|
*/
|
||||||
|
export function string16(n) {
|
||||||
|
const { [kBuffer]: buff } = n;
|
||||||
|
let str = ""
|
||||||
|
for (let i = buff.length - 1; i >= 0; i--) if (buff[i] !== S16_0) while (i >= 0) str += string16B(buff[i--]);
|
||||||
|
return `0x${str.padStart(1, "0")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } n
|
||||||
|
*/
|
||||||
|
export function string8(n) {
|
||||||
|
const { [kBuffer]: buff } = n;
|
||||||
|
let str = ""
|
||||||
|
for (let i = buff.length - 1; i >= 0; i--) if (buff[i] !== S8_0) while (i >= 0) str += string8B(buff[i--]);
|
||||||
|
return `0o${str.padStart(1, "0")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } n
|
||||||
|
*/
|
||||||
|
export function string2(n) {
|
||||||
|
const { [kBuffer]: buff } = n;
|
||||||
|
let str = ""
|
||||||
|
for (let i = buff.length - 1; i >= 0; i--) if (buff[i] !== S2_0) while (i >= 0) str += string2B(buff[i--]);
|
||||||
|
return `0b${str.padStart(1, "0")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } n
|
||||||
|
*/
|
||||||
|
export function string10(n) {
|
||||||
|
const { [kBuffer]: buff } = n;
|
||||||
|
let str = ""
|
||||||
|
for (let i = buff.length - 1; i >= 0; i--) if (buff[i] !== S10_0) while (i >= 0) str += string10B(buff[i--]);
|
||||||
|
return str.padStart(1, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } n
|
||||||
|
*/
|
||||||
|
export function string(n) {
|
||||||
|
switch (n.radix) {
|
||||||
|
case 2: return string2(n);
|
||||||
|
case 8: return string8(n);
|
||||||
|
case 16: return string16(n);
|
||||||
|
case 10: return string10(n);
|
||||||
|
default: throw new Error(`unsupported radix (${n.radix})`);
|
||||||
|
}
|
||||||
|
}
|
20
lab1/string/10B.js
Normal file
20
lab1/string/10B.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { S10_0, S10_1, S10_2, S10_3, S10_4, S10_5, S10_6, S10_7, S10_8, S10_9 } from "../symbol/S10.js"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { symbol } s
|
||||||
|
*/
|
||||||
|
export function string10B(s) {
|
||||||
|
switch (s) {
|
||||||
|
case S10_0: return "0";
|
||||||
|
case S10_1: return "1";
|
||||||
|
case S10_2: return "2";
|
||||||
|
case S10_3: return "3";
|
||||||
|
case S10_4: return "4";
|
||||||
|
case S10_5: return "5";
|
||||||
|
case S10_6: return "6";
|
||||||
|
case S10_7: return "7";
|
||||||
|
case S10_8: return "8";
|
||||||
|
case S10_9: return "9";
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
26
lab1/string/16B.js
Normal file
26
lab1/string/16B.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
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"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { symbol } s
|
||||||
|
*/
|
||||||
|
export function string16B(s) {
|
||||||
|
switch (s) {
|
||||||
|
case S16_0: return "0";
|
||||||
|
case S16_1: return "1";
|
||||||
|
case S16_2: return "2";
|
||||||
|
case S16_3: return "3";
|
||||||
|
case S16_4: return "4";
|
||||||
|
case S16_5: return "5";
|
||||||
|
case S16_6: return "6";
|
||||||
|
case S16_7: return "7";
|
||||||
|
case S16_8: return "8";
|
||||||
|
case S16_9: return "9";
|
||||||
|
case S16_A: return "A";
|
||||||
|
case S16_B: return "B";
|
||||||
|
case S16_C: return "C";
|
||||||
|
case S16_D: return "D";
|
||||||
|
case S16_E: return "E";
|
||||||
|
case S16_F: return "F";
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
12
lab1/string/2B.js
Normal file
12
lab1/string/2B.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { S2_0, S2_1 } from "../symbol/S2.js"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { symbol } s
|
||||||
|
*/
|
||||||
|
export function string2B(s) {
|
||||||
|
switch (s) {
|
||||||
|
case S2_0: return "0";
|
||||||
|
case S2_1: return "1";
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
19
lab1/string/8B.js
Normal file
19
lab1/string/8B.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { S8_0, S8_1, S8_2, S8_3, S8_4, S8_5, S8_6, S8_7 } from "../symbol/S8.js"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { symbol } s
|
||||||
|
*/
|
||||||
|
export function string8B(s) {
|
||||||
|
switch (s) {
|
||||||
|
case S8_0: return "0";
|
||||||
|
case S8_1: return "1";
|
||||||
|
case S8_2: return "2";
|
||||||
|
case S8_3: return "3";
|
||||||
|
case S8_4: return "4";
|
||||||
|
case S8_5: return "5";
|
||||||
|
case S8_6: return "6";
|
||||||
|
case S8_7: return "7";
|
||||||
|
default: throw new Error("unexpected symbol");
|
||||||
|
}
|
||||||
|
}
|
15
lab1/sub.js
Normal file
15
lab1/sub.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* @import { Num } from "./num.js"
|
||||||
|
*/
|
||||||
|
import { add } from "./add.js";
|
||||||
|
import { not } from "./not.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { Num } a
|
||||||
|
* @param { Num } b
|
||||||
|
*/
|
||||||
|
export function sub(a, b) {
|
||||||
|
b = b.copy();
|
||||||
|
not(b);
|
||||||
|
add(a, b);
|
||||||
|
}
|
10
lab1/symbol/S10.js
Normal file
10
lab1/symbol/S10.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export const S10_0 = Symbol("0");
|
||||||
|
export const S10_1 = Symbol("1");
|
||||||
|
export const S10_2 = Symbol("2");
|
||||||
|
export const S10_3 = Symbol("3");
|
||||||
|
export const S10_4 = Symbol("4");
|
||||||
|
export const S10_5 = Symbol("5");
|
||||||
|
export const S10_6 = Symbol("6");
|
||||||
|
export const S10_7 = Symbol("7");
|
||||||
|
export const S10_8 = Symbol("8");
|
||||||
|
export const S10_9 = Symbol("9");
|
16
lab1/symbol/S16.js
Normal file
16
lab1/symbol/S16.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
export const S16_0 = Symbol("0");
|
||||||
|
export const S16_1 = Symbol("1");
|
||||||
|
export const S16_2 = Symbol("2");
|
||||||
|
export const S16_3 = Symbol("3");
|
||||||
|
export const S16_4 = Symbol("4");
|
||||||
|
export const S16_5 = Symbol("5");
|
||||||
|
export const S16_6 = Symbol("6");
|
||||||
|
export const S16_7 = Symbol("7");
|
||||||
|
export const S16_8 = Symbol("8");
|
||||||
|
export const S16_9 = Symbol("9");
|
||||||
|
export const S16_A = Symbol("A");
|
||||||
|
export const S16_B = Symbol("B");
|
||||||
|
export const S16_C = Symbol("C");
|
||||||
|
export const S16_D = Symbol("D");
|
||||||
|
export const S16_E = Symbol("E");
|
||||||
|
export const S16_F = Symbol("F");
|
2
lab1/symbol/S2.js
Normal file
2
lab1/symbol/S2.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export const S2_0 = Symbol("0");
|
||||||
|
export const S2_1 = Symbol("1");
|
8
lab1/symbol/S8.js
Normal file
8
lab1/symbol/S8.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export const S8_0 = Symbol("0");
|
||||||
|
export const S8_1 = Symbol("1");
|
||||||
|
export const S8_2 = Symbol("2");
|
||||||
|
export const S8_3 = Symbol("3");
|
||||||
|
export const S8_4 = Symbol("4");
|
||||||
|
export const S8_5 = Symbol("5");
|
||||||
|
export const S8_6 = Symbol("6");
|
||||||
|
export const S8_7 = Symbol("7");
|
7
lab1/utils.js
Normal file
7
lab1/utils.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* @param { unknown } err
|
||||||
|
* @returns { never }
|
||||||
|
*/
|
||||||
|
export function __throw(err) {
|
||||||
|
throw err;
|
||||||
|
}
|
362
lab2/index.js
Normal file
362
lab2/index.js
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
import { at } from "./utilities.js";
|
||||||
|
|
||||||
|
const L = 4;
|
||||||
|
const MAX = 9999;
|
||||||
|
const LIM = 10000;
|
||||||
|
|
||||||
|
const kBuffer = Symbol("buffer");
|
||||||
|
|
||||||
|
export class BigInteger {
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static zero = BigInteger.from("0");
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static one = BigInteger.from("1");
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static two = BigInteger.from("2");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { number[] } buffer
|
||||||
|
* @param {boolean} [negative]
|
||||||
|
*/
|
||||||
|
constructor(buffer, negative = false) {
|
||||||
|
this[kBuffer] = buffer;
|
||||||
|
this.negative = negative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { string } str
|
||||||
|
*/
|
||||||
|
static from(str) {
|
||||||
|
const negative = str[0] === "-";
|
||||||
|
if (negative) str = str.substring(1);
|
||||||
|
/**@type { number[] } */
|
||||||
|
const buffer = [];
|
||||||
|
let i = str.length;
|
||||||
|
let j = i - L;
|
||||||
|
while (j > 0) {
|
||||||
|
buffer.push(Number.parseInt(str.substring(j, i)));
|
||||||
|
j -= L;
|
||||||
|
i -= L;
|
||||||
|
}
|
||||||
|
buffer.push(Number.parseInt(str.substring(0, i)));
|
||||||
|
return new BigInteger(buffer, negative);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { BigInteger } a
|
||||||
|
* @param { BigInteger } b
|
||||||
|
*/
|
||||||
|
static ucmp(a, b) {
|
||||||
|
const l = a[kBuffer].length;
|
||||||
|
if (l !== b[kBuffer].length) return l > b[kBuffer].length ? 1 : -1;
|
||||||
|
for (let i = l - 1; i >= 0; i--) {
|
||||||
|
if (a[kBuffer][i] !== b[kBuffer][i]) return a[kBuffer][i] > b[kBuffer][i] ? 1 : -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { BigInteger } num
|
||||||
|
*/
|
||||||
|
static isZero(num) {
|
||||||
|
return num[kBuffer].length === 1 && num[kBuffer][0] === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { boolean } [negative]
|
||||||
|
* @returns { BigInteger }
|
||||||
|
*/
|
||||||
|
copy(negative = this.negative) {
|
||||||
|
return new BigInteger(Array.from(this[kBuffer]), negative);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns { BigInteger }
|
||||||
|
*/
|
||||||
|
shallowCopy() {
|
||||||
|
return new BigInteger(this[kBuffer], this.negative);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { BigInteger } num
|
||||||
|
* @param { boolean } [negative]
|
||||||
|
* @returns { this }
|
||||||
|
*/
|
||||||
|
assign(num, negative = num.negative) {
|
||||||
|
this[kBuffer] = Array.from(num[kBuffer]);
|
||||||
|
this.negative = negative;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns { this }
|
||||||
|
*/
|
||||||
|
toggleSign() {
|
||||||
|
this.negative = !this.negative;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { boolean } negative
|
||||||
|
* @returns { this }
|
||||||
|
*/
|
||||||
|
setSign(negative) {
|
||||||
|
this.negative = negative;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
const buff = this[kBuffer];
|
||||||
|
let accum = this.negative ? "-" : "";
|
||||||
|
accum += buff[buff.length - 1].toString();
|
||||||
|
for (let i = buff.length - 2; i >= 0; i--) accum += buff[i].toString().padStart(4, "0");
|
||||||
|
return accum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { BigInteger } num
|
||||||
|
* @param { boolean } [negative]
|
||||||
|
* @returns { this }
|
||||||
|
*/
|
||||||
|
add(num, negative = num.negative) {
|
||||||
|
if (this.negative !== negative) return this.negative ? this.sub(num, true) : this.sub(num, false);
|
||||||
|
const buffA = this[kBuffer];
|
||||||
|
const buffB = num[kBuffer];
|
||||||
|
let carry = 0;
|
||||||
|
for (let i = 0; i < buffB.length; i++) {
|
||||||
|
while (buffA.length <= i) buffA.push(0);
|
||||||
|
buffA[i] += buffB[i] + carry;
|
||||||
|
carry = Number(buffA[i] > MAX);
|
||||||
|
if (carry) buffA[i] %= LIM;
|
||||||
|
}
|
||||||
|
if (carry) {
|
||||||
|
let i = buffB.length;
|
||||||
|
while (buffA.length <= i) buffA.push(0);
|
||||||
|
while (buffA[i] === MAX) {
|
||||||
|
buffA[i++] = 0;
|
||||||
|
while (buffA.length <= i) buffA.push(0);
|
||||||
|
}
|
||||||
|
buffA[i] += carry;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @param { BigInteger } num
|
||||||
|
// * @param { boolean } [negative]
|
||||||
|
// * @returns { this }
|
||||||
|
// */
|
||||||
|
// add(num, negative = num.negative) {
|
||||||
|
// if (this.negative !== negative) return this.sub(num, this.negative);
|
||||||
|
// return this.uadd(num);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @param { BigInteger } num
|
||||||
|
// * @returns { this }
|
||||||
|
// */
|
||||||
|
// uadd(num) {
|
||||||
|
// const buffA = this[kBuffer];
|
||||||
|
// const buffB = num[kBuffer];
|
||||||
|
// let carry = 0;
|
||||||
|
// let i = 0;
|
||||||
|
// while (buffA.length < buffB.length) buffA.push(0);
|
||||||
|
// for (; i < buffB.length; i++) {
|
||||||
|
// buffA[i] += buffB[i] + carry;
|
||||||
|
// carry = Number(buffA[i] > MAX);
|
||||||
|
// if (carry) buffA[i] %= LIM;
|
||||||
|
// }
|
||||||
|
// if (carry === 1) {
|
||||||
|
// while (at(buffA, i, 0) === MAX) buffA[i++] = 0;
|
||||||
|
// buffA[i] += carry;
|
||||||
|
// }
|
||||||
|
// return this;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { BigInteger } num
|
||||||
|
* @param { boolean } [negative]
|
||||||
|
* @returns { this }
|
||||||
|
*/
|
||||||
|
sub(num, negative = num.negative) {
|
||||||
|
if (this.negative !== negative) return this.negative ? this.add(num, true) : this.add(num, false);
|
||||||
|
if (BigInteger.ucmp(num, this) == 1) {
|
||||||
|
const self = this.shallowCopy();
|
||||||
|
return this.assign(num, negative).sub(self).toggleSign();
|
||||||
|
}
|
||||||
|
const buffA = this[kBuffer];
|
||||||
|
const buffB = num[kBuffer];
|
||||||
|
let carry = 0;
|
||||||
|
for (let i = 0; i < buffB.length; i++) {
|
||||||
|
buffA[i] -= buffB[i] + carry;
|
||||||
|
carry = Number(buffA[i] < 0);
|
||||||
|
if (carry) buffA[i] += LIM;
|
||||||
|
}
|
||||||
|
if (carry) {
|
||||||
|
let i = buffB.length;
|
||||||
|
while (buffA[i] === 0) buffA[i++] = MAX;
|
||||||
|
buffA[i] -= carry;
|
||||||
|
}
|
||||||
|
while (buffA.length > 1 && buffA[buffA.length - 1] == 0) buffA.pop();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @param { BigInteger } num
|
||||||
|
// * @param { boolean } [negative]
|
||||||
|
// * @returns { this }
|
||||||
|
// */
|
||||||
|
// sub(num, negative = num.negative) {
|
||||||
|
// if (this.negative !== negative) return this.add(num, this.negative);
|
||||||
|
// return this.usub(num);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @param { BigInteger } num
|
||||||
|
// * @returns { this }
|
||||||
|
// */
|
||||||
|
// usub(num) {
|
||||||
|
// if (BigInteger.ucmp(num, this) == 1) {
|
||||||
|
// const self = this.shallowCopy();
|
||||||
|
// return this.assign(num, !this.negative).usub(self)
|
||||||
|
// }
|
||||||
|
// const buffA = this[kBuffer];
|
||||||
|
// const buffB = num[kBuffer];
|
||||||
|
// let carry = 0;
|
||||||
|
// let i = 0;
|
||||||
|
// for (; i < buffB.length; i++) {
|
||||||
|
// buffA[i] -= buffB[i] + carry;
|
||||||
|
// carry = Number(buffA[i] < 0);
|
||||||
|
// if (carry) buffA[i] += LIM;
|
||||||
|
// }
|
||||||
|
// if (carry == 1) {
|
||||||
|
// while (buffA[i] === 0) buffA[i++] = MAX;
|
||||||
|
// buffA[i] -= carry;
|
||||||
|
// }
|
||||||
|
// for (let i = buffA.length - 1; i > 0 && buffA[i] === 0; i--) buffA.pop();
|
||||||
|
// return this;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { BigInteger } num
|
||||||
|
* @returns { this }
|
||||||
|
*/
|
||||||
|
mul(num) {
|
||||||
|
/**@type { number[] } */
|
||||||
|
const buff = [];
|
||||||
|
for (let i = 0; i < this[kBuffer].length; i++) {
|
||||||
|
const a = this[kBuffer][i];
|
||||||
|
for (let j = 0; j < num[kBuffer].length; j++) {
|
||||||
|
const b = num[kBuffer][j];
|
||||||
|
let k = i + j;
|
||||||
|
while (buff.length <= k) buff.push(0);
|
||||||
|
buff[k] += a * b;
|
||||||
|
while (buff[k] > MAX) {
|
||||||
|
const carry = Math.trunc(buff[k] / LIM)
|
||||||
|
buff[k++] %= LIM;
|
||||||
|
while (buff.length <= k) buff.push(0);
|
||||||
|
buff[k] += carry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this[kBuffer] = buff;
|
||||||
|
this.negative = this.negative !== num.negative;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @param { BigInteger } num
|
||||||
|
// * @returns { this }
|
||||||
|
// */
|
||||||
|
// mul(num) {
|
||||||
|
// return this.umul(num).setSign(this.negative !== num.negative);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @param { BigInteger } num
|
||||||
|
// * @returns { this }
|
||||||
|
// */
|
||||||
|
// umul(num) {
|
||||||
|
// /**@type { number[] } */
|
||||||
|
// const buff = [];
|
||||||
|
// for (let i = 0; i < this[kBuffer].length; i++) {
|
||||||
|
// const a = this[kBuffer][i];
|
||||||
|
// for (let j = 0; j < num[kBuffer].length; j++) {
|
||||||
|
// const b = num[kBuffer][j];
|
||||||
|
// let k = i + j;
|
||||||
|
// while (buff.length <= k) buff.push(0);
|
||||||
|
// buff[k] += a * b;
|
||||||
|
// while (buff[k] > MAX) {
|
||||||
|
// const carry = Math.trunc(buff[k] / LIM)
|
||||||
|
// buff[k++] %= LIM;
|
||||||
|
// while (buff.length <= k) buff.push(0);
|
||||||
|
// buff[k] += carry;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// this[kBuffer] = buff;
|
||||||
|
// return this;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { BigInteger } num
|
||||||
|
* @returns { this }
|
||||||
|
*/
|
||||||
|
div(num) {
|
||||||
|
const buffB = num[kBuffer];
|
||||||
|
const l = buffB.length - 1;
|
||||||
|
let quick = true;
|
||||||
|
for (let i = 0; i < l && quick; i++) quick = (buffB[i] == 0);
|
||||||
|
if (quick) {
|
||||||
|
const D = buffB[l];
|
||||||
|
const N = this[kBuffer].slice(l);
|
||||||
|
let carry = 0;
|
||||||
|
for (let i = N.length - 1; i >= 0; i--) {
|
||||||
|
N[i] += (carry * LIM);
|
||||||
|
carry = N[i] % D;
|
||||||
|
N[i] = Math.trunc(N[i] / D);
|
||||||
|
}
|
||||||
|
if (N.length < 1) N.push(0);
|
||||||
|
while (N.length > 1 && N[N.length - 1] == 0) N.pop();
|
||||||
|
this[kBuffer] = N;
|
||||||
|
this.negative = this.negative !== num.negative;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const A = num.copy();
|
||||||
|
for (let i = 0; i < l; i++) A[kBuffer][i] = 0;
|
||||||
|
const Q = this.copy().div(A);
|
||||||
|
const R = num.copy().add(BigInteger.one, num.negative);
|
||||||
|
const TMP = BigInteger.zero.copy();
|
||||||
|
while (BigInteger.ucmp(R, num) != -1) {
|
||||||
|
TMP.assign(Q).mul(num);
|
||||||
|
R.assign(this).sub(TMP);
|
||||||
|
TMP.assign(R).div(A).add(Q);
|
||||||
|
Q.add(TMP).div(BigInteger.two);
|
||||||
|
}
|
||||||
|
TMP.assign(Q).mul(num);
|
||||||
|
R.assign(this).sub(TMP);
|
||||||
|
if (this.negative !== R.negative && !BigInteger.isZero(R)) {
|
||||||
|
Q.sub(BigInteger.one, Q.negative);
|
||||||
|
R.add(num);
|
||||||
|
}
|
||||||
|
this[kBuffer] = Q[kBuffer];
|
||||||
|
this.negative = Q.negative;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { BigInteger } num
|
||||||
|
* @returns { this }
|
||||||
|
*/
|
||||||
|
udiv(num) {
|
||||||
|
throw new Error("Not Implemented");
|
||||||
|
}
|
||||||
|
}
|
261
lab2/test.js
Normal file
261
lab2/test.js
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
import { BigInteger } from "./index.js"
|
||||||
|
|
||||||
|
console.group("Addition and subtraction")
|
||||||
|
console.group("by 0 is the identity")
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("1").add(BigInteger.from("0")).toString() === "1");
|
||||||
|
console.assert(BigInteger.from("-1").add(BigInteger.from("0")).toString() === "-1");
|
||||||
|
console.assert(BigInteger.from("0").add(BigInteger.from("-1")).toString() === "-1");
|
||||||
|
console.assert(BigInteger.from("0").add(BigInteger.from("153")).toString() === "153");
|
||||||
|
console.assert(BigInteger.from("153").add(BigInteger.from("0")).toString() === "153");
|
||||||
|
console.assert(BigInteger.from("0").add(BigInteger.from("-153")).toString() === "-153");
|
||||||
|
console.assert(BigInteger.from("-153").add(BigInteger.from("0")).toString() === "-153");
|
||||||
|
console.assert(BigInteger.from("0").add(BigInteger.from("9844190321790980841789")).toString() === "9844190321790980841789");
|
||||||
|
console.assert(BigInteger.from("9844190321790980841789").add(BigInteger.from("0")).toString() ==="9844190321790980841789");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("0").add(BigInteger.from("-9844190321790980841789")).toString() ==="-9844190321790980841789");
|
||||||
|
console.assert(BigInteger.from("-9844190321790980841789").add(BigInteger.from("0")).toString() === "-9844190321790980841789");
|
||||||
|
console.assert(BigInteger.from("1").sub(BigInteger.from("0")).toString() === "1");
|
||||||
|
console.assert(BigInteger.from("-1").sub(BigInteger.from("0")).toString() === "-1");
|
||||||
|
console.assert(BigInteger.from("153").sub(BigInteger.from("0")).toString() === "153");
|
||||||
|
console.assert(BigInteger.from("-153").sub(BigInteger.from("0")).toString() === "-153");
|
||||||
|
console.assert(BigInteger.from("9844190321790980841789").sub(BigInteger.from("0")).toString() === "9844190321790980841789");
|
||||||
|
console.assert(BigInteger.from("-9844190321790980841789").sub(BigInteger.from("0")).toString() === "-9844190321790980841789");
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.group("addition by inverse is 0, subtraction by self is 0");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("5").sub(BigInteger.from("5")).toString() === "0");
|
||||||
|
console.assert(BigInteger.from("5").add(BigInteger.from("-5")).toString() === "0");
|
||||||
|
console.assert(BigInteger.from("10000000000000000").sub(BigInteger.from("10000000000000000")).toString() === "0");
|
||||||
|
console.assert(BigInteger.from("10000000000000000").add(BigInteger.from("-10000000000000000")).toString() === "0");
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.group("handles signs correctly");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("1").add(BigInteger.from("1")).toString() === "2");
|
||||||
|
console.assert(BigInteger.from("1").add(BigInteger.from("-5")).toString() === "-4");
|
||||||
|
console.assert(BigInteger.from("-1").add(BigInteger.from("5")).toString() === "4");
|
||||||
|
console.assert(BigInteger.from("-1").add(BigInteger.from("-5")).toString() === "-6");
|
||||||
|
console.assert(BigInteger.from("5").add(BigInteger.from("1")).toString() === "6");
|
||||||
|
console.assert(BigInteger.from("5").add(BigInteger.from("-1")).toString() === "4");
|
||||||
|
console.assert(BigInteger.from("-5").add(BigInteger.from("1")).toString() === "-4");
|
||||||
|
console.assert(BigInteger.from("-5").add(BigInteger.from("-1")).toString() === "-6");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("1").sub(BigInteger.from("1")).toString() === "0");
|
||||||
|
console.assert(BigInteger.from("1").sub(BigInteger.from("-5")).toString() === "6");
|
||||||
|
console.assert(BigInteger.from("-1").sub(BigInteger.from("5")).toString() === "-6");
|
||||||
|
console.assert(BigInteger.from("-1").sub(BigInteger.from("-5")).toString() === "4");
|
||||||
|
console.assert(BigInteger.from("5").sub(BigInteger.from("1")).toString() === "4");
|
||||||
|
console.assert(BigInteger.from("5").sub(BigInteger.from("-1")).toString() === "6");
|
||||||
|
console.assert(BigInteger.from("-5").sub(BigInteger.from("1")).toString() === "-6");
|
||||||
|
console.assert(BigInteger.from("-5").sub(BigInteger.from("-1")).toString() === "-4");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("1234698764971301").add(BigInteger.from("5")).toString() === "1234698764971306");
|
||||||
|
console.assert(BigInteger.from("1234698764971301").add(BigInteger.from("-5")).toString() === "1234698764971296");
|
||||||
|
console.assert(BigInteger.from("-1234698764971301").add(BigInteger.from("5")).toString() === "-1234698764971296");
|
||||||
|
console.assert(BigInteger.from("-1234698764971301").add(BigInteger.from("-5")).toString() === "-1234698764971306");
|
||||||
|
console.assert(BigInteger.from("5").add(BigInteger.from("1234698764971301")).toString() === "1234698764971306");
|
||||||
|
console.assert(BigInteger.from("5").add(BigInteger.from("-1234698764971301")).toString() === "-1234698764971296");
|
||||||
|
console.assert(BigInteger.from("-5").add(BigInteger.from("1234698764971301")).toString() === "1234698764971296");
|
||||||
|
console.assert(BigInteger.from("-5").add(BigInteger.from("-1234698764971301")).toString() === "-1234698764971306");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("1234698764971301").sub(BigInteger.from("5")).toString() === "1234698764971296");
|
||||||
|
console.assert(BigInteger.from("1234698764971301").sub(BigInteger.from("-5")).toString() === "1234698764971306");
|
||||||
|
console.assert(BigInteger.from("-1234698764971301").sub(BigInteger.from("5")).toString() === "-1234698764971306");
|
||||||
|
console.assert(BigInteger.from("-1234698764971301").sub(BigInteger.from("-5")).toString() === "-1234698764971296");
|
||||||
|
console.assert(BigInteger.from("5").sub(BigInteger.from("1234698764971301")).toString() === "-1234698764971296");
|
||||||
|
console.assert(BigInteger.from("5").sub(BigInteger.from("-1234698764971301")).toString() === "1234698764971306");
|
||||||
|
console.assert(BigInteger.from("-5").sub(BigInteger.from("1234698764971301")).toString() === "-1234698764971306");
|
||||||
|
console.assert(BigInteger.from("-5").sub(BigInteger.from("-1234698764971301")).toString() === "1234698764971296");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("1234567890987654321").add(BigInteger.from("9876543210123456789")).toString() === "11111111101111111110");
|
||||||
|
console.assert(BigInteger.from("1234567890987654321").add(BigInteger.from("-9876543210123456789")).toString() === "-8641975319135802468");
|
||||||
|
console.assert(BigInteger.from("-1234567890987654321").add(BigInteger.from("9876543210123456789")).toString() === "8641975319135802468");
|
||||||
|
console.assert(BigInteger.from("-1234567890987654321").add(BigInteger.from("-9876543210123456789")).toString() === "-11111111101111111110");
|
||||||
|
console.assert(BigInteger.from("9876543210123456789").add(BigInteger.from("1234567890987654321")).toString() === "11111111101111111110");
|
||||||
|
console.assert(BigInteger.from("9876543210123456789").add(BigInteger.from("-1234567890987654321")).toString() === "8641975319135802468");
|
||||||
|
console.assert(BigInteger.from("-9876543210123456789").add(BigInteger.from("1234567890987654321")).toString() === "-8641975319135802468");
|
||||||
|
console.assert(BigInteger.from("-9876543210123456789").add(BigInteger.from("-1234567890987654321")).toString() === "-11111111101111111110");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("1234567890987654321").sub(BigInteger.from("9876543210123456789")).toString() === "-8641975319135802468");
|
||||||
|
console.assert(BigInteger.from("1234567890987654321").sub(BigInteger.from("-9876543210123456789")).toString() === "11111111101111111110");
|
||||||
|
console.assert(BigInteger.from("-1234567890987654321").sub(BigInteger.from("9876543210123456789")).toString() === "-11111111101111111110");
|
||||||
|
console.assert(BigInteger.from("-1234567890987654321").sub(BigInteger.from("-9876543210123456789")).toString() === "8641975319135802468");
|
||||||
|
console.assert(BigInteger.from("9876543210123456789").sub(BigInteger.from("1234567890987654321")).toString() === "8641975319135802468");
|
||||||
|
console.assert(BigInteger.from("9876543210123456789").sub(BigInteger.from("-1234567890987654321")).toString() === "11111111101111111110");
|
||||||
|
console.assert(BigInteger.from("-9876543210123456789").sub(BigInteger.from("1234567890987654321")).toString() === "-11111111101111111110");
|
||||||
|
console.assert(BigInteger.from("-9876543210123456789").sub(BigInteger.from("-1234567890987654321")).toString() === "-8641975319135802468");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("-9007199254740991").add(BigInteger.from("-1")).toString() === "-9007199254740992");
|
||||||
|
console.assert(BigInteger.from("-5616421592529327000000000000000").sub(BigInteger.from("987682355516543")).toString() === "-5616421592529327987682355516543")
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("-0").add(BigInteger.from("10000000000000000")).toString() === "10000000000000000");
|
||||||
|
console.assert(BigInteger.from("-0").add(BigInteger.from("-1")).toString() ==="-1");
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.group("carries over correctly");
|
||||||
|
{
|
||||||
|
const fibs = ["1", "1", "2", "3", "5", "8", "13", "21", "34", "55", "89", "144", "233", "377", "610", "987", "1597", "2584", "4181", "6765", "10946", "17711", "28657", "46368", "75025", "121393", "196418", "317811", "514229", "832040", "1346269", "2178309", "3524578", "5702887", "9227465", "14930352", "24157817", "39088169", "63245986", "102334155", "165580141", "267914296", "433494437", "701408733", "1134903170", "1836311903", "2971215073", "4807526976", "7778742049", "12586269025"];
|
||||||
|
const number = BigInteger.from("1");
|
||||||
|
const last = BigInteger.from("1");
|
||||||
|
|
||||||
|
for (let i = 2; i < 50; i++) {
|
||||||
|
number.add(last);
|
||||||
|
last.assign(number.copy().sub(last));
|
||||||
|
|
||||||
|
console.assert(number.toString() === fibs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("9007199254740991").add(BigInteger.from("1")).toString() === "9007199254740992");
|
||||||
|
console.assert(BigInteger.from("999999999999999999999000000000000000000000").add(BigInteger.from("1000000000000000000000")).toString() === "1000000000000000000000000000000000000000000");
|
||||||
|
console.assert(BigInteger.from("100000000000000000000").add(BigInteger.from("9007199254740972")).toString() === "100009007199254740972");
|
||||||
|
console.assert(BigInteger.from("-9007199254740983").add(BigInteger.from("-9999999999999998")).toString() === "-19007199254740981");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("100000000000000000000000000000000000").sub(BigInteger.from("999999999999999999")).toString() === "99999999999999999000000000000000001");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("10000000010000000").sub(BigInteger.from("10000000")).toString() === "10000000000000000");
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.group("work");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("10").add(BigInteger.from("10")).toString() === "20");
|
||||||
|
console.assert(BigInteger.from("-10000000000000000").add(BigInteger.from("0")).toString() === "-10000000000000000");
|
||||||
|
console.assert(BigInteger.from("0").add(BigInteger.from("10000000000000000")).toString() === "10000000000000000");
|
||||||
|
console.assert(BigInteger.from("9999999").add(BigInteger.from("1")).toString() === "10000000");
|
||||||
|
console.assert(BigInteger.from("10000000").sub(BigInteger.from("1")).toString() === "9999999");
|
||||||
|
console.assert(BigInteger.from("-1000000000000000000000000000000000001").add(BigInteger.from("1000000000000000000000000000000000000")).toString() === "-1");
|
||||||
|
console.assert(BigInteger.from("100000000000000000002222222222222222222").sub(BigInteger.from("100000000000000000001111111111111111111")).toString() === "1111111111111111111");
|
||||||
|
console.assert(BigInteger.from("1").add(BigInteger.from("0")).toString() === "1");
|
||||||
|
console.assert(BigInteger.from("10").add(BigInteger.from("10000000000000000")).toString() === "10000000000000010");
|
||||||
|
console.assert(BigInteger.from("10000000000000000").add(BigInteger.from("10")).toString() === "10000000000000010");
|
||||||
|
console.assert(BigInteger.from("10000000000000000").add(BigInteger.from("10000000000000000")).toString() === "20000000000000000");
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.groupEnd();
|
||||||
|
|
||||||
|
console.group("Multiplication")
|
||||||
|
console.group("by 0 equals 0");
|
||||||
|
|
||||||
|
// console.assert(BigInteger.from("0").mul(BigInteger.from("0")).toString() === "0");
|
||||||
|
// console.assert(BigInteger.from("0").mul(BigInteger.from("-0")).toString() === "0");
|
||||||
|
// console.assert(BigInteger.from("1").mul(BigInteger.from("0")).toString() === "-0");
|
||||||
|
// console.assert(BigInteger.from("-0").mul(BigInteger.from("1")).toString() === "0");
|
||||||
|
// console.assert(BigInteger.from("1234567890987654321").mul(BigInteger.from("0")).toString() ==="-0");
|
||||||
|
// console.assert(BigInteger.from("-0").mul(BigInteger.from("1234567890987654321")).toString() === "0");
|
||||||
|
// console.assert(BigInteger.from("0").mul(BigInteger.from("-1234567890987654321")).toString() === "0");
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.group("by 1 is the identity")
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("1").mul(BigInteger.from("1")).toString() === "1");
|
||||||
|
console.assert(BigInteger.from("-1").mul(BigInteger.from("1")).toString() === "-1");
|
||||||
|
console.assert(BigInteger.from("1").mul(BigInteger.from("-1")).toString() === "-1");
|
||||||
|
console.assert(BigInteger.from("1").mul(BigInteger.from("153")).toString() === "153");
|
||||||
|
console.assert(BigInteger.from("153").mul(BigInteger.from("1")).toString() === "153");
|
||||||
|
console.assert(BigInteger.from("1").mul(BigInteger.from("-153")).toString() === "-153");
|
||||||
|
console.assert(BigInteger.from("-153").mul(BigInteger.from("1")).toString() === "-153");
|
||||||
|
console.assert(BigInteger.from("1").mul(BigInteger.from("9844190321790980841789")).toString() === "9844190321790980841789");
|
||||||
|
console.assert(BigInteger.from("9844190321790980841789").mul(BigInteger.from("1")).toString() === "9844190321790980841789");
|
||||||
|
console.assert(BigInteger.from("1").mul(BigInteger.from("-9844190321790980841789")).toString() === "-9844190321790980841789");
|
||||||
|
console.assert(BigInteger.from("-9844190321790980841789").mul(BigInteger.from("1")).toString() === "-9844190321790980841789");
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.group("handles signs correctly");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("100").mul(BigInteger.from("100")).toString() === "10000");
|
||||||
|
console.assert(BigInteger.from("100").mul(BigInteger.from("-100")).toString() === "-10000");
|
||||||
|
console.assert(BigInteger.from("-100").mul(BigInteger.from("100")).toString() === "-10000");
|
||||||
|
console.assert(BigInteger.from("-100").mul(BigInteger.from("-100")).toString() === "10000");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("13579").mul(BigInteger.from("163500573666152634716420931676158")).toString() === "2220174289812686626814279831230549482");
|
||||||
|
console.assert(BigInteger.from("13579").mul(BigInteger.from("-163500573666152634716420931676158")).toString() === "-2220174289812686626814279831230549482");
|
||||||
|
console.assert(BigInteger.from("-13579").mul(BigInteger.from("163500573666152634716420931676158")).toString() === "-2220174289812686626814279831230549482");
|
||||||
|
console.assert(BigInteger.from("-13579").mul(BigInteger.from("-163500573666152634716420931676158")).toString() === "2220174289812686626814279831230549482");
|
||||||
|
console.assert(BigInteger.from("163500573666152634716420931676158").mul(BigInteger.from("13579")).toString() === "2220174289812686626814279831230549482");
|
||||||
|
console.assert(BigInteger.from("163500573666152634716420931676158").mul(BigInteger.from("-13579")).toString() === "-2220174289812686626814279831230549482");
|
||||||
|
console.assert(BigInteger.from("-163500573666152634716420931676158").mul(BigInteger.from("13579")).toString() === "-2220174289812686626814279831230549482");
|
||||||
|
console.assert(BigInteger.from("-163500573666152634716420931676158").mul(BigInteger.from("-13579")).toString() === "2220174289812686626814279831230549482");
|
||||||
|
console.assert(BigInteger.from("163500573666152634716420931676158").mul(BigInteger.from("-1")).toString() === "-163500573666152634716420931676158");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("1234567890987654321").mul(BigInteger.from("132435465768798")).toString() === "163500573666152634716420931676158");
|
||||||
|
console.assert(BigInteger.from("1234567890987654321").mul(BigInteger.from("-132435465768798")).toString() === "-163500573666152634716420931676158");
|
||||||
|
console.assert(BigInteger.from("-1234567890987654321").mul(BigInteger.from("132435465768798")).toString() === "-163500573666152634716420931676158");
|
||||||
|
console.assert(BigInteger.from("-1234567890987654321").mul(BigInteger.from("-132435465768798")).toString() === "163500573666152634716420931676158");
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.group("carries over correctly");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("50000005000000").mul(BigInteger.from("10000001")).toString() === "500000100000005000000");
|
||||||
|
console.assert(BigInteger.from("50000005000000").mul(BigInteger.from("10000001")).toString() === "500000100000005000000");
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.groupEnd();
|
||||||
|
|
||||||
|
console.group("Division")
|
||||||
|
console.group("by 1 is the identity");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("1").div(BigInteger.from("1")).toString() === "1");
|
||||||
|
console.assert(BigInteger.from("-1").div(BigInteger.from("1")).toString() === "-1");
|
||||||
|
console.assert(BigInteger.from("1").div(BigInteger.from("-1")).toString() === "-1");
|
||||||
|
console.assert(BigInteger.from("153").div(BigInteger.from("1")).toString() === "153");
|
||||||
|
console.assert(BigInteger.from("-153").div(BigInteger.from("1")).toString() === "-153");
|
||||||
|
console.assert(BigInteger.from("9844190321790980841789").div(BigInteger.from("1")).toString() === "9844190321790980841789");
|
||||||
|
console.assert(BigInteger.from("-9844190321790980841789").div(BigInteger.from("1")).toString() === "-9844190321790980841789");
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.group("by self is 1");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("5").div(BigInteger.from("5")).toString() === "1");
|
||||||
|
console.assert(BigInteger.from("-5").div(BigInteger.from("-5")).toString() === "1");
|
||||||
|
console.assert(BigInteger.from("20194965098495006574").div(BigInteger.from("20194965098495006574")).toString() === "1");
|
||||||
|
console.assert(BigInteger.from("-20194965098495006574").div(BigInteger.from("-20194965098495006574")).toString() === "1");
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.group("of 0 equals 0");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("0").div(BigInteger.from("1")).toString() === "0");
|
||||||
|
console.assert(BigInteger.from("-0").div(BigInteger.from("1")).toString() === "-0");
|
||||||
|
console.assert(BigInteger.from("-0").div(BigInteger.from("1234567890987654321")).toString() === "-0");
|
||||||
|
console.assert(BigInteger.from("0").div(BigInteger.from("-1234567890987654321")).toString() === "-0");
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.group("handles signs correctly");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("10000").div(BigInteger.from("100")).toString() === "100");
|
||||||
|
console.assert(BigInteger.from("10000").div(BigInteger.from("-100")).toString() === "-100");
|
||||||
|
console.assert(BigInteger.from("-10000").div(BigInteger.from("100")).toString() === "-100");
|
||||||
|
console.assert(BigInteger.from("-10000").div(BigInteger.from("-100")).toString() === "100");
|
||||||
|
console.assert(BigInteger.from("100").div(BigInteger.from("-1000")).toString() === "-0");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("163500573666152634716420931676158").div(BigInteger.from("13579")).toString() === "12040693251797086288859336598");
|
||||||
|
console.assert(BigInteger.from("163500573666152634716420931676158").div(BigInteger.from("-13579")).toString() === "-12040693251797086288859336598");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("-163500573666152634716420931676158").div(BigInteger.from("13579")).toString() === "-12040693251797086288859336598");
|
||||||
|
console.assert(BigInteger.from("-163500573666152634716420931676158").div(BigInteger.from("-13579")).toString() === "12040693251797086288859336598");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("1234567890987654321").div(BigInteger.from("132435465768798")).toString() === "9322");
|
||||||
|
console.assert(BigInteger.from("1234567890987654321").div(BigInteger.from("-132435465768798")).toString() === "-9322");
|
||||||
|
console.assert(BigInteger.from("-1234567890987654321").div(BigInteger.from("132435465768798")).toString() === "-9322");
|
||||||
|
console.assert(BigInteger.from("-1234567890987654321").div(BigInteger.from("-132435465768798")).toString() === "9322");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("786456456335437356436").div(BigInteger.from("-5423424653")).toString() === "-145011041298");
|
||||||
|
console.assert(BigInteger.from("-93453764643534523").div(BigInteger.from("-2342")).toString() === "39903400787162");
|
||||||
|
console.assert(BigInteger.from("10000000000000000").div(BigInteger.from("-10000000000000000")).toString() === "-1");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("98789789419609840614360398703968368740365403650364036403645046").div(BigInteger.from("-1")).toString() === "-98789789419609840614360398703968368740365403650364036403645046");
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.group("works");
|
||||||
|
|
||||||
|
console.assert(BigInteger.from("98109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241981098409840984091564810684565416840659648198410651068657103974645132104164354016450306480360340639740650049510942094209420974219704902741950491209742109742097421902740927404920974209298924909742022419810984098409840915648106845654168406596481984106510686571039746451321041643540164503064803603406397406500495109420942094209742197049027419504912097421097420974219027409274049209742092989249097420224198109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241981098409840984091564810684565416840659648198410651068657103974645132104164354016450306480360340639740650049510942094209420974219704902741950491209742109742097421902740927404920974209298924909742022419810984098409840915648106845654168406596481984106510686571039746451321041643540164503064803603406397406500495109420942094209742197049027419504912097421097420974219027409274049209742092989249097420224198109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241981098409840984091564810684565416840659648198410651068657103974645132104164354016450306480360340639740650049510942094209420974219704902741950491209742109742097421902740927404920974209298924909742022419810984098409840915648106845654168406596481984106510686571039746451321041643540164503064803603406397406500495109420942094209742197049027419504912097421097420974219027409274049209742092989249097420224198109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241").div(BigInteger.from("98109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241")).toString() === "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
|
||||||
|
console.assert(BigInteger.from("650891045068740450350436540352434350243346254305240433565403624570436542564034355230360437856406345450735366803660233645540323657640436735034636550432635454032364560324366403643455063652403346540263364032643454530236455402336455640363263405423565405623454062354540326564062306456432664546654436564364556406435460643646363545606345066534456065340165344065234064564").div(BigInteger.from("2634565230452364554234565062345452365450236455423654456253445652344565423655423655462534506253450462354056523445062535462534052654350426355023654540625344056203455402635454026435501635446643754664546780646476442344654465764466744566754436556406235454066354570657548036545465")).toString() === "247058238507527885509216194910087226997858456323482112332514020694766925604284002588230023");
|
||||||
|
console.assert(BigInteger.from("650891045068740450350436540352434350243346254305240433565403624570436542564034355230360437856406345450735366803660233645540323657640436735034636550432635454032364560324366403643455063652403346540263364032643454530236455402336455640363263405423565405623454062354540326564062306456432664546654436564364556406435460643646363545606345066534456065340165344065234064564000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").div(BigInteger.from("2634565230452364554234565062345452365450236455423654456253445652344565423655423655462534506253450462354056523445062535462534052654350426355023654540625344056203455402635454026435501635446643754664546780646476442344654465764466744566754436556406235454066354570657548036545465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")).toString() === "247058238507527885509216194910087226997858456323482112332514020694766925604284002588230023");
|
||||||
|
console.assert(BigInteger.from("9999999999999900000000000000").div(BigInteger.from("999999999999990000001")).toString() === "9999999");
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.groupEnd();
|
||||||
|
console.groupEnd();
|
||||||
|
|
||||||
|
console.log("done");
|
9
lab2/utilities.js
Normal file
9
lab2/utilities.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* @param { number[] } array
|
||||||
|
* @param { number } index
|
||||||
|
* @param { number } init
|
||||||
|
*/
|
||||||
|
export function at(array, index, init) {
|
||||||
|
while (array.length <= index) array.push(init);
|
||||||
|
return array[index];
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user