Skip to content

Commit

Permalink
Euclidian algorithm tests pass for bounded numbers, which means all t…
Browse files Browse the repository at this point in the history
…ests pass for the first time in years, yaaaaay!
  • Loading branch information
DanielKrawisz committed Aug 23, 2022
1 parent 1f1f6a1 commit f9f0ec4
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 42 deletions.
2 changes: 1 addition & 1 deletion include/data/encoding/halves.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ namespace data::encoding {

template <typename half>
typename twice<half>::type inline subtract(half a, half b, half r) {
return (typename twice<half>::type)(a) - b + r;
return r + a - b;
};

template <typename half>
Expand Down
62 changes: 31 additions & 31 deletions include/data/encoding/words.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@

namespace data::arithmetic {

// Note: some of the type and var names in the following functions
// are very confusing. It would be good to fix them.
template <typename sen, typename it>
requires std::input_iterator<it> && std::sentinel_for<sen, it>
bool equal(sen z, it i, it j) {
Expand Down Expand Up @@ -61,19 +59,19 @@ namespace data::arithmetic {
return std::weak_ordering::equivalent;
}

template <typename digit, typename sen, typename ita, typename itb>
requires std::input_iterator<itb> && std::output_iterator<ita, digit> && std::sentinel_for<sen, ita>
void bit_negate(sen z, ita i, itb j) {
template <typename digit, typename sen, typename ito, typename iti>
requires std::sentinel_for<sen, ito> && std::output_iterator<ito, digit> && std::input_iterator<iti>
void bit_negate(sen z, ito i, iti j) {
while (i != z) {
*i = ~ *j;
i++;
j++;
}
}

template <typename digit, typename sen, typename ita, typename itb>
requires std::input_iterator<itb> && std::output_iterator<ita, digit> && std::sentinel_for<sen, ita>
void bit_and(sen z, ita i, itb a, itb b) {
template <typename digit, typename sen, typename ito, typename iti>
requires std::sentinel_for<sen, ito> && std::output_iterator<ito, digit> && std::input_iterator<iti>
void bit_and(sen z, ito i, iti a, iti b) {
while (i != z) {
*i = *a & *b;
i++;
Expand All @@ -82,9 +80,9 @@ namespace data::arithmetic {
}
}

template <typename digit, typename sen, typename ita, typename itb>
requires std::input_iterator<itb> && std::output_iterator<ita, digit> && std::sentinel_for<sen, ita>
void bit_or(sen z, ita i, itb a, itb b) {
template <typename digit, typename sen, typename ito, typename iti>
requires std::sentinel_for<sen, ito> && std::output_iterator<ito, digit> && std::input_iterator<iti>
void bit_or(sen z, ito i, iti a, iti b) {
while (i != z) {
*i = *a | *b;
i++;
Expand All @@ -93,9 +91,9 @@ namespace data::arithmetic {
}
}

template <typename digit, typename sen, typename ita, typename itb>
requires std::input_iterator<itb> && std::output_iterator<ita, digit> && std::sentinel_for<sen, ita>
void bit_xor(sen z, ita i, itb a, itb b) {
template <typename digit, typename sen, typename ito, typename iti>
requires std::sentinel_for<sen, ito> && std::output_iterator<ito, digit> && std::input_iterator<iti>
void bit_xor(sen z, ito i, iti a, iti b) {
while (i != z) {
*i = *a ^ *b;
i++;
Expand All @@ -104,9 +102,9 @@ namespace data::arithmetic {
}
}

template <typename digit, typename sen, typename ita, typename itb>
requires std::input_iterator<itb> && std::output_iterator<ita, digit> && std::sentinel_for<sen, ita>
digit plus(sen z, ita a, digit d, itb b) {
template <typename digit, typename sen, typename ito, typename iti>
requires std::sentinel_for<sen, ito> && std::output_iterator<ito, digit> && std::input_iterator<iti>
digit plus(sen z, ito a, digit d, iti b) {
using two_digits = typename encoding::twice<digit>::type;

digit remainder = d;
Expand All @@ -122,9 +120,9 @@ namespace data::arithmetic {
return remainder;
}

template <typename digit, typename sen, typename ita, typename itb>
requires std::input_iterator<itb> && std::output_iterator<ita, digit> && std::sentinel_for<sen, ita>
digit minus(sen z, ita a, digit d, itb b) {
template <typename digit, typename sen, typename ito, typename iti>
requires std::sentinel_for<sen, ito> && std::output_iterator<ito, digit> && std::input_iterator<iti>
digit minus(sen z, ito a, digit d, iti b) {
digit remainder = d;
while (a != z) {
if (*b >= remainder) {
Expand All @@ -141,9 +139,9 @@ namespace data::arithmetic {
return remainder;
}

template <typename digit, typename sen, typename ita, typename itb>
requires std::input_iterator<itb> && std::output_iterator<ita, digit> && std::sentinel_for<sen, ita>
digit plus(sen z, ita i, itb a, itb b) {
template <typename digit, typename sen, typename ito, typename iti>
requires std::sentinel_for<sen, ito> && std::output_iterator<ito, digit> && std::input_iterator<iti>
digit plus(sen z, ito i, iti a, iti b) {
using two_digits = typename encoding::twice<digit>::type;

digit remainder = 0;
Expand All @@ -160,28 +158,30 @@ namespace data::arithmetic {
return remainder;
}

template <typename digit, typename sen, typename ita, typename itb>
requires std::input_iterator<itb> && std::output_iterator<ita, digit> && std::sentinel_for<sen, ita>
digit minus(sen z, ita a, itb b, itb i) {
template <typename digit, typename sen, typename ito, typename iti>
requires std::sentinel_for<sen, ito> && std::output_iterator<ito, digit> && std::input_iterator<iti>
digit minus(sen z, ito i, iti a, iti b) {
using two_digits = typename encoding::twice<digit>::type;

digit remainder = 0;
two_digits remainder = 0;

int dig = 0;
while (i != z) {
two_digits result = encoding::subtract<digit>(*a, *b, remainder);
remainder = encoding::greater_half(result);
*i = encoding::lesser_half(result);
i++;
a++;
b++;
dig ++;
}

return remainder;
}

template <typename digit, typename sen, typename ita, typename itb>
requires std::input_iterator<itb> && std::output_iterator<ita, digit> && std::sentinel_for<sen, ita>
digit times(sen z, ita a, itb b, itb i) {
template <typename digit, typename sen, typename ito, typename iti>
requires std::sentinel_for<sen, ito> && std::output_iterator<ito, digit> && std::input_iterator<iti>
digit times(sen z, ito i, iti a, iti b) {
using two_digits = typename encoding::twice<digit>::type;

digit remainder = 0;
Expand Down Expand Up @@ -232,7 +232,7 @@ namespace data::arithmetic {

// you have to use reverse iterators for this function.
template <typename sen, typename ita, typename itb>
requires std::input_iterator<itb> && std::output_iterator<ita, byte> && std::sentinel_for<sen, ita>
requires std::input_iterator<itb> && std::output_iterator<ita, byte> && std::sentinel_for<sen, itb>
void shift_right(ita &i, sen z, itb b, byte amount, byte fill) {
using two_digits = typename encoding::twice<byte>::type;

Expand Down
25 changes: 17 additions & 8 deletions include/data/math/number/bounded/bounded.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <data/encoding/halves.hpp>
#include <data/math/number/bytes/N.hpp>
#include <data/encoding/words.hpp>
#include <data/io/wait_for_enter.hpp>

namespace data::math::number {

Expand Down Expand Up @@ -476,21 +477,21 @@ namespace data::math::number {
sint<r, size> operator+(const sint<r, size> &a, const uint<r, size> &b) {
sint<r, size> x;
std::copy(b.begin(), b.end(), x.begin());
return a + b;
return a + x;
}

template <endian::order r, size_t size>
sint<r, size> operator-(const sint<r, size> &a, const uint<r, size> &b) {
sint<r, size> x;
std::copy(b.begin(), b.end(), x.begin());
return a - b;
return a - x;
}

template <endian::order r, size_t size>
sint<r, size> operator*(const sint<r, size> &a, const uint<r, size> &b) {
sint<r, size> x;
std::copy(b.begin(), b.end(), x.begin());
return a * b;
return a * x;
}

}
Expand Down Expand Up @@ -781,16 +782,24 @@ namespace data::math::number {
}

template <bool u, endian::order o, size_t size>
bounded<u, o, size> inline operator-(const bounded<u, o, size> &a, const bounded<u, o, size> &n) {
bounded<u, o, size> operator-(const bounded<u, o, size> &a, const bounded<u, o, size> &n) {
bounded<u, o, size> z;
std::copy(n.begin(), n.end(), z.begin());
z.bit_negate();
++z;
bounded<u, o, size> x;
data::arithmetic::minus<byte>(x.words().end(), x.words().begin(), a.words().begin(), n.words().begin());
data::arithmetic::minus<byte>(x.words().end(), x.words().begin(), a.words().begin(), z.words().begin());
return x;
}

template <bool u, endian::order o, size_t size>
bounded<u, o, size> inline &operator-=(bounded<u, o, size> &a, const bounded<u, o, size> &n) {
data::arithmetic::minus<byte>(a.words().end(), a.words().begin(),
const_cast<const bounded<u, o, size>&>(a).words().begin(), n.words().begin());
bounded<u, o, size> &operator-=(bounded<u, o, size> &a, const bounded<u, o, size> &n) {
bounded<u, o, size> z;
std::copy(n.begin(), n.end(), z.begin());
z.bit_negate();
++z;
data::arithmetic::plus<byte>(a.words().end(), a.words().begin(),
const_cast<const bounded<u, o, size>&>(a).words().begin(), z.words().begin());
return a;
}

Expand Down
4 changes: 2 additions & 2 deletions test/testExtendedEuclidian.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ namespace data {
test_extended_euclidian<int64, int64> {};
test_extended_euclidian<Z, N>{};
test_extended_euclidian<Zl1, Nl>{};
test_extended_euclidian<Zb1, Nb>{};/*
test_extended_euclidian<Zb1, Nb>{};
test_extended_euclidian<int_big<9>, uint_big<9>>{};
test_extended_euclidian<int_big<10>, uint_big<10>>{};
test_extended_euclidian<int_big<11>, uint_big<11>>{};
test_extended_euclidian<int_big<20>, uint_big<20>>{};*/
test_extended_euclidian<int_big<20>, uint_big<20>>{};

}

Expand Down

0 comments on commit f9f0ec4

Please sign in to comment.