Skip to content

Commit

Permalink
redo polynomial, division functions for number types, fix many bugs.
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielKrawisz committed Dec 29, 2023
1 parent 32ef2c9 commit 2f09ba9
Show file tree
Hide file tree
Showing 36 changed files with 1,229 additions and 732 deletions.
8 changes: 8 additions & 0 deletions include/data/encoding/base58.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,14 @@ namespace data::math {
bool is_zero (const base58_uint &);
bool is_negative (const base58_uint &);
bool is_positive (const base58_uint &);

template <>
struct divide<base58_uint> {
division<base58_uint> operator () (const base58_uint &v, const base58_uint &z) {
auto d = divide<N> {} (N (v), N (z));
return {encoding::base58::encode (d.Quotient), encoding::base58::encode (d.Remainder)};
}
};

}

Expand Down
25 changes: 25 additions & 0 deletions include/data/encoding/endian/arithmetic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <data/encoding/words.hpp>
#include <data/math/abs.hpp>
#include <data/math/sign.hpp>
#include <data/math/division.hpp>

namespace data::endian {

Expand Down Expand Up @@ -264,6 +265,30 @@ namespace data::math {
return x > 0;
}

template <endian::order r, size_t x>
struct divide<endian::arithmetic<false, r, x>, endian::arithmetic<false, r, x>> {
division<endian::arithmetic<false, r, x>, endian::arithmetic<false, r, x>> operator ()
(const endian::arithmetic<false, r, x> &v, const endian::arithmetic<false, r, x> &z) {
return {v / z, v % z};
}
};

template <endian::order r, size_t x>
struct divide<endian::arithmetic<true, r, x>, endian::arithmetic<true, r, x>> {
division<endian::arithmetic<true, r, x>, endian::arithmetic<false, r, x>> operator ()
(const endian::arithmetic<true, r, x> &v, const endian::arithmetic<true, r, x> &z) {
return {v / z, v % z};
}
};

template <endian::order r, size_t x>
struct divide<endian::arithmetic<true, r, x>, endian::arithmetic<false, r, x>> {
division<endian::arithmetic<true, r, x>, endian::arithmetic<false, r, x>> operator ()
(const endian::arithmetic<true, r, x> &v, const endian::arithmetic<false, r, x> &z) {
return {v / z, v % z};
}
};

}

namespace data {
Expand Down
62 changes: 59 additions & 3 deletions include/data/encoding/integer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,16 @@ namespace data::math {
template <hex_case zz> struct abs<hex::int2<zz>> {
hex::int2<zz> operator () (const hex::int2<zz> &);
};

template <> struct times<dec_int> {
dec_int operator () (const dec_int &, const dec_int &);
nonzero<dec_int> operator () (const nonzero<dec_int> &, const nonzero<dec_int> &);
};

template <number::complement c, hex_case zz> struct times<hex::integer<c, zz>> {
hex::integer<c, zz> operator () (const hex::integer<c, zz> &, const hex::integer<c, zz> &);
nonzero<hex::integer<c, zz>> operator () (const nonzero<hex::integer<c, zz>> &, const nonzero<hex::integer<c, zz>> &);
};

template <> struct commutative<plus<dec_uint>, dec_uint> {};
template <> struct associative<plus<dec_uint>, dec_uint> {};
Expand Down Expand Up @@ -490,6 +500,38 @@ namespace data::math {

template <hex_case cx>
bool is_negative_zero (const hex::int2<cx> &);

template <> struct divide<dec_uint, dec_uint> {
division<dec_uint, dec_uint> operator () (const dec_uint &, const dec_uint &);
};

template <> struct divide<dec_int, dec_int> {
division<dec_int, dec_uint> operator () (const dec_int &, const dec_int &);
};

template <> struct divide<dec_int, dec_uint> {
division<dec_int, dec_uint> operator () (const dec_int &, const dec_uint &);
};

template <hex_case zz>
struct divide<hex::uint<zz>, hex::uint<zz>> {
division<hex::uint<zz>, hex::uint<zz>> operator () (const hex::uint<zz> &, const hex::uint<zz> &);
};

template <hex_case zz>
struct divide<hex::int1<zz>, hex::int1<zz>> {
division<hex::int1<zz>, hex::uint<zz>> operator () (const hex::int1<zz> &, const hex::int1<zz> &);
};

template <hex_case zz>
struct divide<hex::int1<zz>, hex::uint<zz>> {
division<hex::int1<zz>, hex::uint<zz>> operator () (const hex::int1<zz> &, const hex::uint<zz> &);
};

template <hex_case zz>
struct divide<hex::int2<zz>, hex::int2<zz>> {
division<hex::int2<zz>, hex::int2<zz>> operator () (const hex::int2<zz> &, const hex::int2<zz> &);
};

}

Expand Down Expand Up @@ -576,6 +618,7 @@ namespace data::encoding::decimal {

explicit operator double () const;
explicit operator uint64 () const;
explicit operator math::N () const;
};

signed_decimal::string operator - (const string &);
Expand Down Expand Up @@ -621,6 +664,7 @@ namespace data::encoding::signed_decimal {

explicit operator double () const;
explicit operator int64 () const;
explicit operator math::Z () const;
};

template <endian::order r>
Expand Down Expand Up @@ -662,6 +706,8 @@ namespace data::encoding::hexidecimal {
integer<c, cx> operator + (int64) const;
integer<c, cx> operator - (int64) const;
integer<c, cx> operator * (int64) const;

explicit operator math::Z () const;
};

template <hex::letter_case cx>
Expand All @@ -677,6 +723,8 @@ namespace data::encoding::hexidecimal {
data::hex::uint<cx> operator + (uint64) const;
data::hex::uint<cx> operator - (uint64) const;
data::hex::uint<cx> operator * (uint64) const;

explicit operator math::N () const;
};

template <complement c, hex::letter_case cx>
Expand Down Expand Up @@ -995,9 +1043,17 @@ namespace data::encoding::signed_decimal {
string inline &operator &= (string &n, const decimal::string &x) {
return n &= string {static_cast<const std::string> (x)};
}

string inline operator / (const string &n, const decimal::string &x) {
return n / string {static_cast<const std::string> (x)};

string inline operator / (const string &v, const decimal::string &z) {
return math::divide<string, decimal::string> {} (v, z).Quotient;
}

string inline operator / (const string &v, const string &z) {
return math::divide<string, string> {} (v, z).Quotient;
}

decimal::string inline operator % (const string &v, const decimal::string &z) {
return math::divide<string, decimal::string> {} (v, z).Remainder;
}

string inline operator ++ (string &x, int) {
Expand Down
3 changes: 3 additions & 0 deletions include/data/encoding/words.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

namespace data::encoding {

// words is for iterating over digits that have an endian order.
// Using words, you will always iterate from least to most
// significant digits. Reverse iteration will go from most to least.
template <endian::order o, typename digit> struct words;

template <typename digit> struct words<endian::little, digit> {
Expand Down
20 changes: 19 additions & 1 deletion include/data/float.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#define DATA_FLOAT

#include <data/math/abs.hpp>
#include <data/math/arithmetic.hpp>
#include <data/math/algebra.hpp>
#include <data/math/commutative.hpp>
#include <data/math/associative.hpp>

Expand Down Expand Up @@ -120,6 +120,18 @@ namespace data::math {
return x * x;
}
};

template <std::floating_point X> struct times<X> {
X operator () (const X &a, const X &b) {
return a * b;
}

// technically, it is not true that there are no zero divisors but
// we use floats as an approximation for real numbers.
nonzero<X> operator () (const nonzero<X> &a, const nonzero<X> &b) {
return a * b;
}
};

template <std::floating_point X> struct commutative<plus<X>, X> {};
template <std::floating_point X> struct commutative<times<X>, X> {};
Expand All @@ -143,6 +155,12 @@ namespace data::math {
return b - a;
}
};

template <std::floating_point X> struct inverse<times<X>, X> {
nonzero<X> operator () (const nonzero<X> &a, const nonzero<X> &b) {
return b / a;
}
};

}

Expand Down
70 changes: 35 additions & 35 deletions include/data/functional/queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,102 +15,102 @@ namespace data::interface {

template <typename list, typename element>
concept has_queue_constructor = requires (list x, element e) {
{ list{x, e} } -> std::same_as<list>;
{ list {x, e} } -> std::same_as<list>;
} && requires (element e) {
{ list{e} } -> std::same_as<list>;
{ list {e} } -> std::same_as<list>;
};

template <typename list, typename element>
concept has_append_method = requires (list x, element e) {
{ x.append(e) } -> std::convertible_to<list>;
{ x.append (e) } -> std::convertible_to<list>;
};

template <typename list>
concept has_sort_method = requires (list x) {
{ x.sort() } -> std::convertible_to<list>;
{ x.sort () } -> std::convertible_to<list>;
};

}

namespace data {

template <typename list, typename elem> requires interface::has_append_method<list, elem>
inline list append(const list& x, const elem& e) {
return x.append(e);
inline list append (const list &x, const elem &e) {
return x.append (e);
}

}

namespace data::functional {

template <typename L, typename elem = decltype(std::declval<L>().first())>
template <typename L, typename elem = decltype(std::declval<L> ().first())>
concept queue = sequence<const L, elem> && interface::has_append_method<const L, elem> &&
interface::has_queue_constructor<L, elem> && std::default_initializable<L>;

template <queue list>
list take_queue(const list &x, size_t n, const list &z = {});
list take_queue (const list &x, size_t n, const list &z = {});

template <queue list>
list join_queue(const list&a, const list& b) {
if (data::empty(b)) return a;
return join_queue(append(a, first(b)), rest(b));
if (data::empty (b)) return a;
return join_queue (append(a, first(b)), rest(b));
}

template <queue L> requires ordered<element_of<L>>
L merge_queue(const L &a, const L &b, const L &n = {}) {
if (data::empty(a) && data::empty(b)) return reverse(n);
if (data::empty(a)) return merge_queue(a, rest(b), prepend(n, first(b)));
if (data::empty(b)) return merge_queue(rest(a), b, prepend(n, first(a)));
return first(a) < first(b) ?
merge_queue(rest(a), b, prepend(n, first(a))):
merge_queue(a, rest(b), prepend(n, first(b)));
L merge_queue (const L &a, const L &b, const L &n = {}) {
if (data::empty (a) && data::empty(b)) return reverse(n);
if (data::empty (a)) return merge_queue(a, rest(b), prepend(n, first(b)));
if (data::empty (b)) return merge_queue(rest(a), b, prepend(n, first(a)));
return first (a) < first(b) ?
merge_queue (rest (a), b, prepend(n, first(a))):
merge_queue (a, rest(b), prepend(n, first(b)));
}

}

namespace data {

template <functional::queue list>
list select(list l, function<bool (element_of<list>)> satisfies, list found = {}) {
if (data::empty(l)) return found;
auto f0 = first(l);
if (satisfies(f0)) select(rest(l), satisfies, append(found, f0));
return select(rest(l), satisfies, found);
list select (list l, function<bool (element_of<list>)> satisfies, list found = {}) {
if (data::empty (l)) return found;
auto f0 = first (l);
if (satisfies (f0)) select (rest (l), satisfies, append (found, f0));
return select (rest (l), satisfies, found);
}

template <functional::queue L>
L rotate_left(const L x) {
size_t s = size(x);
L rotate_left (const L x) {
size_t s = size (x);
if (s == 0 || s == 1) return x;

return append(rest(x), first(x));
return append (rest (x), first (x));
}

template <functional::queue L>
L rotate_left(const L x, uint32 n) {
L rotate_left (const L x, uint32 n) {
if (n == 0) return x;

size_t s = size(x);
size_t s = size (x);
if (s == 0 || s == 1) return x;

if (n > s) return rotate_left(x, n % s);
return rotate_left(rotate_left(x, n - 1));
if (n > s) return rotate_left (x, n % s);
return rotate_left (rotate_left (x, n - 1));
}

template <functional::queue L>
inline L rotate_right(const L x) {
return reverse(rotate_left(reverse(x)));
inline L rotate_right (const L x) {
return reverse (rotate_left (reverse (x)));
}

template <functional::queue L>
L rotate_right(const L x, uint32 n) {
L rotate_right (const L x, uint32 n) {
if (n == 0) return x;

size_t s = size(x);
size_t s = size (x);
if (s == 0 || s == 1) return x;

if (n > s) return rotate_right(x, n % s);
return rotate_right(rotate_right(x, n - 1));
if (n > s) return rotate_right (x, n % s);
return rotate_right (rotate_right (x, n - 1));
}

}
Expand Down
Loading

0 comments on commit 2f09ba9

Please sign in to comment.