mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:07:45 +00:00
AK: Implement Knuth's algorithm D for dividing UFixedBigInt's
This commit is contained in:
parent
2470fab05e
commit
2d27c98659
4 changed files with 233 additions and 67 deletions
|
@ -9,6 +9,7 @@
|
|||
#include <AK/NumericLimits.h>
|
||||
#include <AK/Random.h>
|
||||
#include <AK/UFixedBigInt.h>
|
||||
#include <AK/UFixedBigIntDivision.h>
|
||||
|
||||
constexpr int test_iterations = 32;
|
||||
|
||||
|
@ -78,6 +79,62 @@ TEST_CASE(div_mod)
|
|||
}
|
||||
}
|
||||
|
||||
TEST_CASE(div_anti_knuth)
|
||||
{
|
||||
EXPECT_EQ((u256 { { 0ull, 0xffffffffffffffffull, 1ull, 0ull } } / u128 { 0x8000000000000001ull, 0xffffffffffffffffull }), 1u);
|
||||
EXPECT_EQ((u128 { { 0xffffffff00000000ull, 1ull } } / u128 { 0xffffffff80000001ull }), 1u);
|
||||
|
||||
srand(0);
|
||||
|
||||
auto generate_u512 = [] {
|
||||
using namespace AK::Detail;
|
||||
|
||||
u512 number;
|
||||
auto& storage = get_storage_of(number);
|
||||
|
||||
static constexpr u32 interesting_words_count = 14;
|
||||
static constexpr NativeWord interesting_words[interesting_words_count] = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
max_word / 4 - 1,
|
||||
max_word / 4,
|
||||
max_word / 2 - 1,
|
||||
max_word / 2,
|
||||
max_word / 2 + 1,
|
||||
max_word / 2 + 2,
|
||||
max_word - 3,
|
||||
max_word - 2,
|
||||
max_word - 1,
|
||||
};
|
||||
for (size_t i = 0; i < storage.size(); ++i) {
|
||||
u32 type = get_random_uniform(interesting_words_count + 1);
|
||||
NativeWord& next_word = storage[i];
|
||||
if (type == interesting_words_count)
|
||||
next_word = get_random<NativeWord>();
|
||||
else
|
||||
next_word = interesting_words[type];
|
||||
}
|
||||
|
||||
return number;
|
||||
};
|
||||
|
||||
for (int i = 0; i < 16384; ++i) {
|
||||
u512 a = generate_u512(), b = generate_u512();
|
||||
if (b == 0)
|
||||
continue;
|
||||
|
||||
u512 mod;
|
||||
u512 div = a.div_mod(b, mod);
|
||||
|
||||
EXPECT_EQ(div * b + mod, a);
|
||||
EXPECT_EQ(div.wide_multiply(b) + mod, a);
|
||||
EXPECT(0 <= mod && mod < b);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE(shifts)
|
||||
{
|
||||
u128 val { 0x1234ULL };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue