diff --git a/include/data/encoding/halves.hpp b/include/data/encoding/halves.hpp index 86411bea..551d620a 100644 --- a/include/data/encoding/halves.hpp +++ b/include/data/encoding/halves.hpp @@ -184,7 +184,7 @@ namespace data::encoding { template typename twice::type inline subtract(half a, half b, half r) { - return (typename twice::type)(a) - b + r; + return r + a - b; }; template diff --git a/include/data/encoding/words.hpp b/include/data/encoding/words.hpp index c0986f0b..3dfd2e28 100644 --- a/include/data/encoding/words.hpp +++ b/include/data/encoding/words.hpp @@ -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 requires std::input_iterator && std::sentinel_for bool equal(sen z, it i, it j) { @@ -61,9 +59,9 @@ namespace data::arithmetic { return std::weak_ordering::equivalent; } - template - requires std::input_iterator && std::output_iterator && std::sentinel_for - void bit_negate(sen z, ita i, itb j) { + template + requires std::sentinel_for && std::output_iterator && std::input_iterator + void bit_negate(sen z, ito i, iti j) { while (i != z) { *i = ~ *j; i++; @@ -71,9 +69,9 @@ namespace data::arithmetic { } } - template - requires std::input_iterator && std::output_iterator && std::sentinel_for - void bit_and(sen z, ita i, itb a, itb b) { + template + requires std::sentinel_for && std::output_iterator && std::input_iterator + void bit_and(sen z, ito i, iti a, iti b) { while (i != z) { *i = *a & *b; i++; @@ -82,9 +80,9 @@ namespace data::arithmetic { } } - template - requires std::input_iterator && std::output_iterator && std::sentinel_for - void bit_or(sen z, ita i, itb a, itb b) { + template + requires std::sentinel_for && std::output_iterator && std::input_iterator + void bit_or(sen z, ito i, iti a, iti b) { while (i != z) { *i = *a | *b; i++; @@ -93,9 +91,9 @@ namespace data::arithmetic { } } - template - requires std::input_iterator && std::output_iterator && std::sentinel_for - void bit_xor(sen z, ita i, itb a, itb b) { + template + requires std::sentinel_for && std::output_iterator && std::input_iterator + void bit_xor(sen z, ito i, iti a, iti b) { while (i != z) { *i = *a ^ *b; i++; @@ -104,9 +102,9 @@ namespace data::arithmetic { } } - template - requires std::input_iterator && std::output_iterator && std::sentinel_for - digit plus(sen z, ita a, digit d, itb b) { + template + requires std::sentinel_for && std::output_iterator && std::input_iterator + digit plus(sen z, ito a, digit d, iti b) { using two_digits = typename encoding::twice::type; digit remainder = d; @@ -122,9 +120,9 @@ namespace data::arithmetic { return remainder; } - template - requires std::input_iterator && std::output_iterator && std::sentinel_for - digit minus(sen z, ita a, digit d, itb b) { + template + requires std::sentinel_for && std::output_iterator && std::input_iterator + digit minus(sen z, ito a, digit d, iti b) { digit remainder = d; while (a != z) { if (*b >= remainder) { @@ -141,9 +139,9 @@ namespace data::arithmetic { return remainder; } - template - requires std::input_iterator && std::output_iterator && std::sentinel_for - digit plus(sen z, ita i, itb a, itb b) { + template + requires std::sentinel_for && std::output_iterator && std::input_iterator + digit plus(sen z, ito i, iti a, iti b) { using two_digits = typename encoding::twice::type; digit remainder = 0; @@ -160,13 +158,14 @@ namespace data::arithmetic { return remainder; } - template - requires std::input_iterator && std::output_iterator && std::sentinel_for - digit minus(sen z, ita a, itb b, itb i) { + template + requires std::sentinel_for && std::output_iterator && std::input_iterator + digit minus(sen z, ito i, iti a, iti b) { using two_digits = typename encoding::twice::type; - digit remainder = 0; + two_digits remainder = 0; + int dig = 0; while (i != z) { two_digits result = encoding::subtract(*a, *b, remainder); remainder = encoding::greater_half(result); @@ -174,14 +173,15 @@ namespace data::arithmetic { i++; a++; b++; + dig ++; } return remainder; } - template - requires std::input_iterator && std::output_iterator && std::sentinel_for - digit times(sen z, ita a, itb b, itb i) { + template + requires std::sentinel_for && std::output_iterator && std::input_iterator + digit times(sen z, ito i, iti a, iti b) { using two_digits = typename encoding::twice::type; digit remainder = 0; @@ -232,7 +232,7 @@ namespace data::arithmetic { // you have to use reverse iterators for this function. template - requires std::input_iterator && std::output_iterator && std::sentinel_for + requires std::input_iterator && std::output_iterator && std::sentinel_for void shift_right(ita &i, sen z, itb b, byte amount, byte fill) { using two_digits = typename encoding::twice::type; diff --git a/include/data/math/number/bounded/bounded.hpp b/include/data/math/number/bounded/bounded.hpp index 3c7493a7..670b5975 100644 --- a/include/data/math/number/bounded/bounded.hpp +++ b/include/data/math/number/bounded/bounded.hpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace data::math::number { @@ -476,21 +477,21 @@ namespace data::math::number { sint operator+(const sint &a, const uint &b) { sint x; std::copy(b.begin(), b.end(), x.begin()); - return a + b; + return a + x; } template sint operator-(const sint &a, const uint &b) { sint x; std::copy(b.begin(), b.end(), x.begin()); - return a - b; + return a - x; } template sint operator*(const sint &a, const uint &b) { sint x; std::copy(b.begin(), b.end(), x.begin()); - return a * b; + return a * x; } } @@ -781,16 +782,24 @@ namespace data::math::number { } template - bounded inline operator-(const bounded &a, const bounded &n) { + bounded operator-(const bounded &a, const bounded &n) { + bounded z; + std::copy(n.begin(), n.end(), z.begin()); + z.bit_negate(); + ++z; bounded x; - data::arithmetic::minus(x.words().end(), x.words().begin(), a.words().begin(), n.words().begin()); + data::arithmetic::minus(x.words().end(), x.words().begin(), a.words().begin(), z.words().begin()); return x; } template - bounded inline &operator-=(bounded &a, const bounded &n) { - data::arithmetic::minus(a.words().end(), a.words().begin(), - const_cast&>(a).words().begin(), n.words().begin()); + bounded &operator-=(bounded &a, const bounded &n) { + bounded z; + std::copy(n.begin(), n.end(), z.begin()); + z.bit_negate(); + ++z; + data::arithmetic::plus(a.words().end(), a.words().begin(), + const_cast&>(a).words().begin(), z.words().begin()); return a; } diff --git a/test/testExtendedEuclidian.cpp b/test/testExtendedEuclidian.cpp index a2669f20..d44148a5 100644 --- a/test/testExtendedEuclidian.cpp +++ b/test/testExtendedEuclidian.cpp @@ -32,11 +32,11 @@ namespace data { test_extended_euclidian {}; test_extended_euclidian{}; test_extended_euclidian{}; - test_extended_euclidian{};/* + test_extended_euclidian{}; test_extended_euclidian, uint_big<9>>{}; test_extended_euclidian, uint_big<10>>{}; test_extended_euclidian, uint_big<11>>{}; - test_extended_euclidian, uint_big<20>>{};*/ + test_extended_euclidian, uint_big<20>>{}; }