forked from boostorg/integer
Revert change as the previous algorithm overflows for all inputs >= half the bit length of the type.
This commit is contained in:
@ -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};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
Reference in New Issue
Block a user