diff --git a/Tests/LibCrypto/CMakeLists.txt b/Tests/LibCrypto/CMakeLists.txt index 7279dba979..e17909529c 100644 --- a/Tests/LibCrypto/CMakeLists.txt +++ b/Tests/LibCrypto/CMakeLists.txt @@ -1,6 +1,7 @@ set(TEST_SOURCES TestAES.cpp TestASN1.cpp + TestBigFraction.cpp TestBigInteger.cpp TestChecksum.cpp TestChaCha20.cpp diff --git a/Tests/LibCrypto/TestBigFraction.cpp b/Tests/LibCrypto/TestBigFraction.cpp new file mode 100644 index 0000000000..8fbf311867 --- /dev/null +++ b/Tests/LibCrypto/TestBigFraction.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024, Tim Ledbetter + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +TEST_CASE(roundtrip_from_string) +{ + Array valid_number_strings { + "0.1"sv, + "-0.1"sv, + "0.9"sv, + "-0.9"sv, + "1.2"sv, + "-1.2"sv, + "610888968122787804679.305596150292503043363"sv, + "-610888968122787804679.305596150292503043363"sv + }; + + for (auto valid_number_string : valid_number_strings) { + auto result = TRY_OR_FAIL(Crypto::BigFraction::from_string(valid_number_string)); + auto precision = valid_number_string.length() - valid_number_string.find('.').value(); + EXPECT_EQ(result.to_byte_string(precision), valid_number_string); + } +} diff --git a/Userland/Libraries/LibCrypto/BigFraction/BigFraction.cpp b/Userland/Libraries/LibCrypto/BigFraction/BigFraction.cpp index 40c6972682..12d48a31dc 100644 --- a/Userland/Libraries/LibCrypto/BigFraction/BigFraction.cpp +++ b/Userland/Libraries/LibCrypto/BigFraction/BigFraction.cpp @@ -36,6 +36,9 @@ ErrorOr BigFraction::from_string(StringView sv) auto fractional_part = TRY(SignedBigInteger::from_base(10, fraction_part_view)); auto fraction_length = UnsignedBigInteger(static_cast(fraction_part_view.length())); + if (!sv.is_empty() && sv[0] == '-') + fractional_part.negate(); + return BigFraction(move(integer_part)) + BigFraction(move(fractional_part), NumberTheory::Power("10"_bigint, move(fraction_length))); }