mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 02:37:36 +00:00
LibCrypto: Add a way to compare UnsignedBigInteger with double
This patch also make SignedBigInteger::compare_to_double make use of the new function.
This commit is contained in:
parent
e03f014e7a
commit
54b8a2b094
7 changed files with 259 additions and 158 deletions
|
@ -660,9 +660,9 @@ TEST_CASE(test_negative_zero_is_not_allowed)
|
|||
}
|
||||
|
||||
TEST_CASE(double_comparisons) {
|
||||
#define EXPECT_LESS_THAN(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::SignedBigInteger::CompareResult::DoubleGreaterThanBigInt)
|
||||
#define EXPECT_GREATER_THAN(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::SignedBigInteger::CompareResult::DoubleLessThanBigInt)
|
||||
#define EXPECT_EQUAL_TO(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::SignedBigInteger::CompareResult::DoubleEqualsBigInt)
|
||||
#define EXPECT_LESS_THAN(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::UnsignedBigInteger::CompareResult::DoubleGreaterThanBigInt)
|
||||
#define EXPECT_GREATER_THAN(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::UnsignedBigInteger::CompareResult::DoubleLessThanBigInt)
|
||||
#define EXPECT_EQUAL_TO(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::UnsignedBigInteger::CompareResult::DoubleEqualsBigInt)
|
||||
{ Crypto::SignedBigInteger zero { 0 };
|
||||
EXPECT_EQUAL_TO(zero, 0.0);
|
||||
EXPECT_EQUAL_TO(zero, -0.0);
|
||||
|
@ -687,6 +687,14 @@ EXPECT_EQUAL_TO(zero, -0.0);
|
|||
EXPECT_GREATER_THAN(one, -1.000001);
|
||||
}
|
||||
|
||||
{
|
||||
double double_infinity = HUGE_VAL;
|
||||
VERIFY(isinf(double_infinity));
|
||||
Crypto::SignedBigInteger one { 1 };
|
||||
EXPECT_LESS_THAN(one, double_infinity);
|
||||
EXPECT_GREATER_THAN(one, -double_infinity);
|
||||
}
|
||||
|
||||
{
|
||||
double double_max_value = NumericLimits<double>::max();
|
||||
double double_below_max_value = nextafter(double_max_value, 0.0);
|
||||
|
@ -938,18 +946,86 @@ TEST_CASE(bigint_from_double)
|
|||
#undef SURVIVES_ROUND_TRIP_SIGNED
|
||||
#undef SURVIVES_ROUND_TRIP_UNSIGNED
|
||||
}
|
||||
|
||||
TEST_CASE(unsigned_bigint_double_comparisons)
|
||||
{
|
||||
#define EXPECT_LESS_THAN(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::UnsignedBigInteger::CompareResult::DoubleGreaterThanBigInt)
|
||||
#define EXPECT_GREATER_THAN(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::UnsignedBigInteger::CompareResult::DoubleLessThanBigInt)
|
||||
#define EXPECT_EQUAL_TO(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::UnsignedBigInteger::CompareResult::DoubleEqualsBigInt)
|
||||
|
||||
{
|
||||
Crypto::UnsignedBigInteger zero { 0 };
|
||||
EXPECT_EQUAL_TO(zero, 0.0);
|
||||
EXPECT_EQUAL_TO(zero, -0.0);
|
||||
}
|
||||
|
||||
{
|
||||
Crypto::UnsignedBigInteger one { 1 };
|
||||
EXPECT_EQUAL_TO(one, 1.0);
|
||||
EXPECT_GREATER_THAN(one, -1.0);
|
||||
EXPECT_GREATER_THAN(one, 0.5);
|
||||
EXPECT_GREATER_THAN(one, -0.5);
|
||||
EXPECT_LESS_THAN(one, 1.000001);
|
||||
}
|
||||
|
||||
{
|
||||
double double_infinity = HUGE_VAL;
|
||||
VERIFY(isinf(double_infinity));
|
||||
Crypto::UnsignedBigInteger one { 1 };
|
||||
EXPECT_LESS_THAN(one, double_infinity);
|
||||
EXPECT_GREATER_THAN(one, -double_infinity);
|
||||
}
|
||||
|
||||
{
|
||||
double double_max_value = NumericLimits<double>::max();
|
||||
double double_below_max_value = nextafter(double_max_value, 0.0);
|
||||
VERIFY(double_below_max_value < double_max_value);
|
||||
VERIFY(double_below_max_value < (double_max_value - 1.0));
|
||||
auto max_value_in_bigint = Crypto::UnsignedBigInteger::from_base(16, "fffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"sv);
|
||||
auto max_value_plus_one = max_value_in_bigint.plus(Crypto::UnsignedBigInteger { 1 });
|
||||
auto max_value_minus_one = max_value_in_bigint.minus(Crypto::UnsignedBigInteger { 1 });
|
||||
|
||||
auto below_max_value_in_bigint = Crypto::UnsignedBigInteger::from_base(16, "fffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"sv);
|
||||
|
||||
EXPECT_EQUAL_TO(max_value_in_bigint, double_max_value);
|
||||
EXPECT_LESS_THAN(max_value_minus_one, double_max_value);
|
||||
EXPECT_GREATER_THAN(max_value_plus_one, double_max_value);
|
||||
EXPECT_LESS_THAN(below_max_value_in_bigint, double_max_value);
|
||||
|
||||
EXPECT_GREATER_THAN(max_value_in_bigint, double_below_max_value);
|
||||
EXPECT_GREATER_THAN(max_value_minus_one, double_below_max_value);
|
||||
EXPECT_GREATER_THAN(max_value_plus_one, double_below_max_value);
|
||||
EXPECT_EQUAL_TO(below_max_value_in_bigint, double_below_max_value);
|
||||
}
|
||||
|
||||
{
|
||||
double just_above_255 = bit_cast<double>(0x406fe00000000001ULL);
|
||||
double just_below_255 = bit_cast<double>(0x406fdfffffffffffULL);
|
||||
double double_255 = 255.0;
|
||||
Crypto::UnsignedBigInteger bigint_255 { 255 };
|
||||
|
||||
EXPECT_EQUAL_TO(bigint_255, double_255);
|
||||
EXPECT_GREATER_THAN(bigint_255, just_below_255);
|
||||
EXPECT_LESS_THAN(bigint_255, just_above_255);
|
||||
}
|
||||
|
||||
#undef EXPECT_LESS_THAN
|
||||
#undef EXPECT_GREATER_THAN
|
||||
#undef EXPECT_EQUAL_TO
|
||||
}
|
||||
|
||||
namespace AK {
|
||||
|
||||
template<>
|
||||
struct Formatter<Crypto::SignedBigInteger::CompareResult> : Formatter<StringView> {
|
||||
ErrorOr<void> format(FormatBuilder& builder, Crypto::SignedBigInteger::CompareResult const& compare_result)
|
||||
struct Formatter<Crypto::UnsignedBigInteger::CompareResult> : Formatter<StringView> {
|
||||
ErrorOr<void> format(FormatBuilder& builder, Crypto::UnsignedBigInteger::CompareResult const& compare_result)
|
||||
{
|
||||
switch (compare_result) {
|
||||
case Crypto::SignedBigInteger::CompareResult::DoubleEqualsBigInt:
|
||||
case Crypto::UnsignedBigInteger::CompareResult::DoubleEqualsBigInt:
|
||||
return builder.put_string("Equals"sv);
|
||||
case Crypto::SignedBigInteger::CompareResult::DoubleLessThanBigInt:
|
||||
case Crypto::UnsignedBigInteger::CompareResult::DoubleLessThanBigInt:
|
||||
return builder.put_string("LessThan"sv);
|
||||
case Crypto::SignedBigInteger::CompareResult::DoubleGreaterThanBigInt:
|
||||
case Crypto::UnsignedBigInteger::CompareResult::DoubleGreaterThanBigInt:
|
||||
return builder.put_string("GreaterThan"sv);
|
||||
default:
|
||||
return builder.put_string("???"sv);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue