mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 00:57:45 +00:00
LibCrypto: Fix subtracting two negative SignedBigInteger
s
Currently, we get the following results
-1 - -2 = -1
-2 - -1 = 1
Correct would be:
-1 - -2 = 1
-2 - -1 = -1
This was already attempted to be fixed in 7ed8970
, but that change was
incorrect. This directly translates to LibJS BigInts having the same
incorrect behavior - it even was tested.
This commit is contained in:
parent
014840eeca
commit
58c6a156bf
3 changed files with 17 additions and 4 deletions
|
@ -543,6 +543,15 @@ TEST_CASE(test_signed_subtraction_simple_subtraction_negative_result)
|
||||||
EXPECT_EQ(num1.minus(num2), Crypto::SignedBigInteger { -20 });
|
EXPECT_EQ(num1.minus(num2), Crypto::SignedBigInteger { -20 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE(test_signed_subtraction_both_negative)
|
||||||
|
{
|
||||||
|
Crypto::SignedBigInteger num1(-50);
|
||||||
|
Crypto::SignedBigInteger num2(-70);
|
||||||
|
|
||||||
|
EXPECT_EQ(num1.minus(num2), Crypto::SignedBigInteger { 20 });
|
||||||
|
EXPECT_EQ(num2.minus(num1), Crypto::SignedBigInteger { -20 });
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE(test_signed_subtraction_simple_subtraction_with_borrow)
|
TEST_CASE(test_signed_subtraction_simple_subtraction_with_borrow)
|
||||||
{
|
{
|
||||||
Crypto::SignedBigInteger num1(Crypto::UnsignedBigInteger { UINT32_MAX });
|
Crypto::SignedBigInteger num1(Crypto::UnsignedBigInteger { UINT32_MAX });
|
||||||
|
|
|
@ -109,11 +109,15 @@ FLATTEN SignedBigInteger SignedBigInteger::minus(const SignedBigInteger& other)
|
||||||
// -x - -y = y - x
|
// -x - -y = y - x
|
||||||
if (m_unsigned_data < other.m_unsigned_data) {
|
if (m_unsigned_data < other.m_unsigned_data) {
|
||||||
// The result will be positive.
|
// The result will be positive.
|
||||||
return SignedBigInteger { other.m_unsigned_data.minus(m_unsigned_data), true };
|
return SignedBigInteger { other.m_unsigned_data.minus(m_unsigned_data) };
|
||||||
}
|
}
|
||||||
// The result will be either zero, or negative.
|
|
||||||
// y - x = - (x - y)
|
// y - x = - (x - y)
|
||||||
return SignedBigInteger { m_unsigned_data.minus(other.m_unsigned_data) };
|
if (m_unsigned_data > other.m_unsigned_data) {
|
||||||
|
// The result will be negative.
|
||||||
|
return SignedBigInteger { m_unsigned_data.minus(other.m_unsigned_data), true };
|
||||||
|
}
|
||||||
|
// Both operands have the same magnitude, the result is positive zero.
|
||||||
|
return SignedBigInteger { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
FLATTEN SignedBigInteger SignedBigInteger::plus(const UnsignedBigInteger& other) const
|
FLATTEN SignedBigInteger SignedBigInteger::plus(const UnsignedBigInteger& other) const
|
||||||
|
|
|
@ -2,7 +2,7 @@ describe("minus behavior", () => {
|
||||||
test("the basics", () => {
|
test("the basics", () => {
|
||||||
expect(3n - 4n).toBe(-1n);
|
expect(3n - 4n).toBe(-1n);
|
||||||
expect(3n - -4n).toBe(7n);
|
expect(3n - -4n).toBe(7n);
|
||||||
expect(-3n - -4n).toBe(-1n);
|
expect(-3n - -4n).toBe(1n);
|
||||||
expect(-3n - 4n).toBe(-7n);
|
expect(-3n - 4n).toBe(-7n);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue