Revert change as the previous algorithm overflows for all inputs >= half the bit length of the type.

This commit is contained in:
Nick Thompson
2018-10-25 18:05:14 -06:00
parent 54d0e4c63e
commit 3f1603938c

View File

@ -10,6 +10,8 @@
#include <limits> #include <limits>
#include <stdexcept> #include <stdexcept>
#include <boost/throw_exception.hpp> #include <boost/throw_exception.hpp>
#include <boost/assert.hpp>
#include <iostream>
namespace boost { namespace integer { namespace boost { namespace integer {
@ -38,26 +40,46 @@ euclidean_result_t<Z> extended_euclidean(Z m, Z n)
BOOST_THROW_EXCEPTION(std::domain_error("Arguments must be strictly positive.\n")); BOOST_THROW_EXCEPTION(std::domain_error("Arguments must be strictly positive.\n"));
} }
Z s = 0; bool swapped = false;
Z old_s = 1; if (m < n)
Z r = n; {
Z old_r = m; swapped = true;
std::swap(m, n);
while (r != 0) { }
Z q = old_r/r; Z u0 = m;
Z tmp = r; Z u1 = 1;
r = old_r - q*tmp; Z u2 = 0;
old_r = tmp; Z v0 = n;
Z v1 = 0;
tmp = s; Z v2 = 1;
s = old_s - q*tmp; Z w0;
old_s = tmp; Z w1;
Z w2;
while(v0 > 0)
{
Z q = u0/v0;
w0 = u0 - q*v0;
w1 = u1 - q*v1;
w2 = u2 - q*v2;
u0 = v0;
u1 = v1;
u2 = v2;
v0 = w0;
v1 = w1;
v2 = w2;
} }
Z y = (old_r - old_s*m)/n; if (swapped)
{
std::swap(u1, u2);
BOOST_ASSERT(u2*m+u1*n==u0);
}
else
{
BOOST_ASSERT(u1*m+u2*n==u0);
}
BOOST_ASSERT(old_s*m+y*n==old_r); return {u0, u1, u2};
return {old_r, old_s, y};
} }
}} }}