psemek/libs/util/tests/big_int.cpp
lisyarus 2c3565df61 32-bit compilation fixes:
* Use uint64_t instead of size_t as hash return value

 * Expect alignof(uint64_t) <= 8 instead of == 8
2025-01-25 20:35:37 +03:00

179 lines
3.2 KiB
C++

#include <psemek/test/test.hpp>
#include <psemek/util/big_int.hpp>
#include <psemek/random/generator.hpp>
#include <psemek/random/uniform.hpp>
using namespace psemek;
using namespace psemek::util;
namespace
{
void check_digits(big_int const & bi, std::vector<big_int::digit> const & digits_expected)
{
span<big_int::digit const> digits_actual = bi.digits();
expect_equal(digits_actual.size(), digits_expected.size());
for (std::size_t i = 0; i < digits_actual.size(); ++i)
expect_equal(digits_actual[i], digits_expected[i]);
}
}
test_case(util_big__int_init_small)
{
{
big_int x;
expect(!x.negative());
check_digits(x, {});
}
{
big_int x(1);
expect(!x.negative());
check_digits(x, {1});
}
{
big_int x(173);
expect(!x.negative());
check_digits(x, {173});
}
{
big_int x(1u << 31);
expect(!x.negative());
check_digits(x, {1u << 31});
}
{
big_int x(1ull << 32);
expect(!x.negative());
check_digits(x, {0, 1});
}
{
big_int x(1ull << 63);
expect(!x.negative());
check_digits(x, {0, 1u << 31});
}
{
big_int x(static_cast<std::uint64_t>(-1));
expect(!x.negative());
check_digits(x, {-1, -1});
}
{
big_int x(-1);
expect(x.negative());
check_digits(x, {1});
}
{
big_int x(-279);
expect(x.negative());
check_digits(x, {279});
}
{
big_int x((-1) << 31);
expect(x.negative());
check_digits(x, {1u << 31});
}
{
big_int x((-1ll) << 32);
expect(x.negative());
check_digits(x, {0, 1u});
}
{
big_int x((-1ll) << 63);
expect(x.negative());
check_digits(x, {0, 1u << 31});
}
{
big_int x(((-1ll) << 62) + ((-1ll) << 15));
expect(x.negative());
check_digits(x, {1u << 15, 1u << 30});
}
}
test_case(util_big__int_init_from__digits)
{
random::generator rng;
{
big_int x = big_int::from_digits(std::vector<int>{});
expect(!x.negative());
check_digits(x, {});
}
{
big_int x = big_int::from_digits(std::vector{5724});
expect(!x.negative());
check_digits(x, {5724});
}
{
big_int x = big_int::from_digits(std::vector{1234, 5678});
expect(!x.negative());
check_digits(x, {1234, 5678});
}
{
big_int x = big_int::from_digits(std::vector{1234, 5678, 0, 0});
expect(!x.negative());
check_digits(x, {1234, 5678});
}
{
std::vector<big_int::digit> digits(64);
for (auto & digit : digits)
digit = random::uniform<big_int::digit>(rng);
if (digits.back() == 0)
digits.back() = 1;
big_int x = big_int::from_digits(digits);
expect(!x.negative());
check_digits(x, digits);
}
{
big_int x = big_int::from_digits(std::vector<int>{}, true);
expect(!x.negative());
check_digits(x, {});
}
{
big_int x = big_int::from_digits(std::vector{5724}, true);
expect(x.negative());
check_digits(x, {5724});
}
{
big_int x = big_int::from_digits(std::vector{1234, 5678}, true);
expect(x.negative());
check_digits(x, {1234, 5678});
}
{
big_int x = big_int::from_digits(std::vector{1234, 5678, 0, 0}, true);
expect(x.negative());
check_digits(x, {1234, 5678});
}
{
std::vector<big_int::digit> digits(64);
for (auto & digit : digits)
digit = random::uniform<big_int::digit>(rng);
if (digits.back() == 0)
digits.back() = 1;
big_int x = big_int::from_digits(digits, true);
expect(x.negative());
check_digits(x, digits);
}
}