mirror of
https://github.com/BorysLevytskyi/BitwiseCmd.git
synced 2026-01-21 11:22:47 +01:00
fix: calculate subtraction by zero (#70)
Previously, subtracting zero (x - 0) would throw an error due to mismatched binary string lengths after two's complement negation, while other operations involving zero worked correctly. This change ensures that: - Zero is properly handled during two's complement negation - Binary strings are consistently padded to full width - Subtraction by zero (x - 0) now correctly returns x Adjust tests to accommodate two's complement of zero. The calculator now behaves consistently for all basic arithmetic identities involving zero. Signed-off-by: Macweese <50101641+macweese@users.noreply.github.com>
This commit is contained in:
@@ -74,11 +74,11 @@ describe('calc.addSpace', () => {
|
||||
describe('calc.numberOfBitsDisplayed', () => {
|
||||
it('calculates number of bits', () => {
|
||||
expect(calc.numberOfBitsDisplayed(1)).toBe(1);
|
||||
expect(calc.numberOfBitsDisplayed(BigInt(-1))).toBe(1);
|
||||
expect(calc.numberOfBitsDisplayed(BigInt(-1))).toBe(32);
|
||||
expect(calc.numberOfBitsDisplayed(2)).toBe(2);
|
||||
expect(calc.numberOfBitsDisplayed(3)).toBe(2);
|
||||
expect(calc.numberOfBitsDisplayed(68719476735)).toBe(36);
|
||||
expect(calc.numberOfBitsDisplayed(INT32_MIN_VALUE-1)).toBe(32);
|
||||
expect(calc.numberOfBitsDisplayed(INT32_MIN_VALUE-1)).toBe(64);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -264,12 +264,12 @@ describe("calc misc", () => {
|
||||
|
||||
it('promoteTo64Bit', () => {
|
||||
const n = asInteger(-1);
|
||||
expect(calc.toBinaryString(calc.promoteTo64Bit(n))).toBe("1");
|
||||
expect(calc.toBinaryString(calc.promoteTo64Bit(n))).toBe("11111111111111111111111111111111");
|
||||
});
|
||||
|
||||
it('binaryRepresentation', () => {
|
||||
|
||||
expect(calc.toBinaryString(Integer.int(-2147483647))).toBe("0000000000000000000000000000001");
|
||||
expect(calc.toBinaryString(Integer.int(-2147483647))).toBe("10000000000000000000000000000001");
|
||||
expect(calc.toBinaryString(asInteger(2147483647))).toBe("1111111111111111111111111111111");
|
||||
});
|
||||
|
||||
@@ -282,7 +282,7 @@ describe("calc misc", () => {
|
||||
const byte = Integer.byte(-127);
|
||||
const int = Integer.int(-127);
|
||||
|
||||
expect(calc.numberOfBitsDisplayed(int)).toBe(7);
|
||||
expect(calc.numberOfBitsDisplayed(int)).toBe(32);
|
||||
expect(calc.numberOfBitsDisplayed(int.abs())).toBe(7);
|
||||
|
||||
// If there is only sign bit left, might as well show it
|
||||
@@ -350,6 +350,8 @@ describe("calc.engine.", () => {
|
||||
it("sub", () => {
|
||||
// 4-bit examples
|
||||
expect(calc.engine.sub("0011", "0001")).toBe("0010"); // 3-1=2
|
||||
expect(calc.engine.sub("0100", "0000")).toBe("0100"); // 4-0=4
|
||||
expect(calc.engine.sub("0100", "0000")).toBe("0100"); // -4-0=-4 (wrap)
|
||||
expect(calc.engine.sub("0000", "0001")).toBe("1111"); // 0-1 -> -1
|
||||
expect(calc.engine.sub("1000", "0001")).toBe("0111"); // -8-1 -> 7 (wrap)
|
||||
});
|
||||
@@ -427,7 +429,7 @@ describe("calc.engine.", () => {
|
||||
expect(calc.engine.applyTwosComplement("010")).toBe("110");
|
||||
expect(calc.engine.applyTwosComplement("110")).toBe("010"); // reverse
|
||||
expect(calc.engine.applyTwosComplement("110")).toBe("010");
|
||||
expect(calc.engine.applyTwosComplement("0")).toBe("10");
|
||||
expect(calc.engine.applyTwosComplement("0")).toBe("0");
|
||||
expect(calc.engine.applyTwosComplement("10101100")).toBe("01010100");
|
||||
expect(calc.engine.applyTwosComplement("01010100")).toBe("10101100"); // reverse
|
||||
});
|
||||
|
||||
@@ -51,11 +51,9 @@ const calc = {
|
||||
if(bin.length > bitSize!)
|
||||
throw new Error(`Binary represenation '${bin}' is bigger than the given bit size ${bitSize}`)
|
||||
|
||||
const r = num.value < 0
|
||||
? this.engine.applyTwosComplement(bin)
|
||||
return num.value < 0
|
||||
? this.engine.applyTwosComplement(bin.padStart(bitSize, '0')) // Pad BEFORE twos complement
|
||||
: bin;
|
||||
|
||||
return bin.length !== bitSize ? r.substring(r.length-bin.length) : r;
|
||||
},
|
||||
|
||||
lshift (num: Integer, numBytes : JsNumber) : Integer {
|
||||
@@ -304,7 +302,7 @@ const calc = {
|
||||
// If there exists no '1' concat 1 at the
|
||||
// starting of string
|
||||
if (lastIndex === -1)
|
||||
return "1" + bin;
|
||||
return bin;
|
||||
|
||||
// Continue traversal backward after the position of
|
||||
// first '1'
|
||||
|
||||
@@ -12,8 +12,8 @@ describe("formatter", () => {
|
||||
const minusOne = BigInt(-1);
|
||||
const n32 = new Integer(minusOne, 32);
|
||||
const n64 = new Integer(minusOne, 64);
|
||||
expect(formatter.bin(n32)).toBe("1");
|
||||
expect(formatter.bin(n64)).toBe("1");
|
||||
expect(formatter.bin(n32)).toBe("11111111111111111111111111111111");
|
||||
expect(formatter.bin(n64)).toBe("1111111111111111111111111111111111111111111111111111111111111111");
|
||||
expect(formatter.fullBin(n32)).toBe("11111111111111111111111111111111");
|
||||
expect(formatter.fullBin(n64)).toBe("1111111111111111111111111111111111111111111111111111111111111111");
|
||||
});
|
||||
@@ -27,10 +27,10 @@ describe("formatter", () => {
|
||||
});
|
||||
|
||||
it('formats negative binary numbers', () => {
|
||||
expect(formatter.numberToString(-1, 'bin')).toBe("1");
|
||||
expect(formatter.numberToString(-1, 'bin')).toBe("11111111111111111111111111111111");
|
||||
expect(formatter.numberToString(-1, 'bin', 32)).toBe("11111111111111111111111111111111");
|
||||
expect(formatter.numberToString(-0, 'bin')).toBe("0");
|
||||
expect(formatter.numberToString(-2147483647, 'bin')).toBe("0000000000000000000000000000001");
|
||||
expect(formatter.numberToString(-2147483647, 'bin')).toBe("10000000000000000000000000000001");
|
||||
});
|
||||
|
||||
it('pads left', () => {
|
||||
|
||||
Reference in New Issue
Block a user