diff --git a/src/bigmath/chain/chain.cpp b/src/bigmath/chain/chain.cpp index 379a014..ef81620 100644 --- a/src/bigmath/chain/chain.cpp +++ b/src/bigmath/chain/chain.cpp @@ -54,9 +54,7 @@ namespace bigmath { chain::chain(chain&& c) noexcept : start(c.start), middle(c.middle), end(c.end) { // Reset source object - c.start = nullptr; - c.middle = nullptr; - c.end = nullptr; + c.start = c.middle = c.end = nullptr; } chain& chain::operator=(const chain& c) noexcept { @@ -71,18 +69,9 @@ namespace bigmath { chain& chain::operator=(chain&& c) noexcept { if (this != &c) { - // Free existing nodes first - this->~chain(); - - // Transfer ownership - start = c.start; - middle = c.middle; - end = c.end; - - // Reset source object - c.start = nullptr; - c.middle = nullptr; - c.end = nullptr; + chain temp(std::move(*this)); + start = c.start; middle = c.middle; end = c.end; + c.start = c.middle = c.end = nullptr; } return *this; } @@ -100,6 +89,40 @@ namespace bigmath { start = middle = end = nullptr; } + chain::operator bool() const noexcept { + return start && middle && end; + } + + std::array chain::split() const noexcept { + // find link* pointers by walking to the middle + if(!start) return { nullptr, nullptr }; + if(start == middle) return { start, end }; + + // <- L [* * *] [{*} * * *] R <- // + chain::link* a_left = end; + chain::link* a_mid = end; + chain::link* a_right = middle->next; + + // this must be odd + while(a_left != a_right) { + a_mid = a_left->prev; + + a_left = a_left->prev; + a_right = a_right->next; + } + + chain::link* b_left = middle; + chain::link* b_right = start; + + // this must be even + while(b_left->next != b_right) { + b_left = b_left->prev; + b_right = b_right->next; + } + + return { b_left, a_mid }; + } + void chain::grow() noexcept { // (*) -> (*) [{*} *] // * (*) * -> * (*) {*} [* *] @@ -227,7 +250,11 @@ namespace bigmath { } // normalize - while(shrink()) ; + while (shrink()); } + // ============================================================================ // + // MULTIPLICATION // + // ============================================================================ // + } diff --git a/src/bigmath/chain/chain.hpp b/src/bigmath/chain/chain.hpp index 28cc5b1..134bfe1 100644 --- a/src/bigmath/chain/chain.hpp +++ b/src/bigmath/chain/chain.hpp @@ -4,6 +4,11 @@ #include +#include + +#include + + namespace bigmath { /** @@ -51,24 +56,32 @@ namespace bigmath { ~chain() noexcept; - public: - - std::array split() noexcept; - public: void add(const chain& c) noexcept; void sub(const chain& c) noexcept; - void mul_long(const chain& c) noexcept; + chain mul_long(const chain& c) noexcept; - void mul_(const chain& c) noexcept; + chain mul_karatsuba(const chain& c) noexcept; - void mul_karatsuba(const chain& c) noexcept; + chain mul_toomcook3(const chain& c) noexcept; + + div_result div_long(const chain& c) noexcept; + + chain div_newtonraphson(const chain& c) noexcept; + + chain div_goldschmidt(const chain& c) noexcept; + + chain div_burnikelziegler(const chain& c) noexcept; public: + operator bool() const noexcept; + + std::array split() const noexcept; + /** * Grows the chain by two links. * This growth strategy keeps the middle diff --git a/src/bigmath/chain/util.hpp b/src/bigmath/chain/util.hpp deleted file mode 100644 index ee0c484..0000000 --- a/src/bigmath/chain/util.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -#include - -namespace bigmath { - - u64 ipow(u64 b, u64 p); - -} \ No newline at end of file diff --git a/src/bigmath/chain/util.cpp b/src/bigmath/util/util.cpp similarity index 100% rename from src/bigmath/chain/util.cpp rename to src/bigmath/util/util.cpp diff --git a/src/bigmath/util/util.hpp b/src/bigmath/util/util.hpp new file mode 100644 index 0000000..7da441b --- /dev/null +++ b/src/bigmath/util/util.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace bigmath { + + template + struct div_result { + T quot; + T remain; + }; + + u64 ipow(u64 b, u64 p); + +} \ No newline at end of file