mirror of
https://github.com/TheAlgorithms/C-Plus-Plus.git
synced 2026-02-08 13:06:57 +08:00
documentation for extended euclid
This commit is contained in:
@@ -1,9 +1,70 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief GCD using [extended Euclid's algorithm]
|
||||
* (https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm)
|
||||
*
|
||||
* Finding coefficients of a and b ie x and y in Bézout's identity
|
||||
* \f[\text{gcd}(a, b) = a \times x + b \times y \f]
|
||||
* This is also used in finding Modular
|
||||
* multiplicative inverse of a number. (A * B)%M == 1 Here B is the MMI of A for
|
||||
* given M, so extendedEuclid (A, M) gives B.
|
||||
*/
|
||||
#include <algorithm> // for swap function
|
||||
#include <iostream>
|
||||
// Finding coefficients of a and b ie x and y in gcd(a, b) = a * x + b * y
|
||||
// d is gcd(a, b)
|
||||
// This is also used in finding Modular multiplicative inverse of a number.
|
||||
// (A * B)%M == 1 Here B is the MMI of A for given M,
|
||||
// so extendedEuclid (A, M) gives B.
|
||||
|
||||
/**
|
||||
* function to update the coefficients per iteration
|
||||
* \f[r_0,\,r = r,\, r_0 - \text{quotient}\times r\f]
|
||||
*
|
||||
* @param[in,out] r signed
|
||||
* @param[in,out] r0 signed
|
||||
* @param[in] quotient unsigned input
|
||||
*/
|
||||
template <typename T, typename T2>
|
||||
inline void update_step(T &r, T &r0, const T2 quotient) {
|
||||
T temp = r;
|
||||
r = r0 - (quotient * temp);
|
||||
r0 = temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation using iterative algorithm from
|
||||
* [Wikipedia](https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Pseudocode)
|
||||
*
|
||||
* @param[in] A unsigned
|
||||
* @param[in] B unsigned
|
||||
* @param[out] GCD unsigned
|
||||
* @param[out] x signed
|
||||
* @param[out] y signed
|
||||
*/
|
||||
template <typename T1, typename T2>
|
||||
void extendedEuclid_1(T1 A, T1 B, T1 *GCD, T2 *x, T2 *y) {
|
||||
if (B > A) std::swap(A, B); // Ensure that A >= B
|
||||
|
||||
T2 s = 0, s0 = 1;
|
||||
T2 t = 1, t0 = 0;
|
||||
T1 r = B, r0 = A;
|
||||
|
||||
while (r != 0) {
|
||||
T1 quotient = r0 / r;
|
||||
update_step(r, r0, quotient);
|
||||
update_step(s, s0, quotient);
|
||||
update_step(t, t0, quotient);
|
||||
}
|
||||
*GCD = r0;
|
||||
*x = s0;
|
||||
*y = t0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation using recursive algorithm
|
||||
*
|
||||
* @param[in] A unsigned
|
||||
* @param[in] B unsigned
|
||||
* @param[out] GCD unsigned
|
||||
* @param[in,out] x signed
|
||||
* @param[in,out] y signed
|
||||
*/
|
||||
template <typename T, typename T2>
|
||||
void extendedEuclid(T A, T B, T *GCD, T2 *x, T2 *y) {
|
||||
if (B > A) std::swap(A, B); // Ensure that A >= B
|
||||
@@ -20,11 +81,14 @@ void extendedEuclid(T A, T B, T *GCD, T2 *x, T2 *y) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Main function
|
||||
int main() {
|
||||
uint32_t a, b, gcd;
|
||||
int32_t x, y;
|
||||
std::cin >> a >> b;
|
||||
extendedEuclid(a, b, &gcd, &x, &y);
|
||||
std::cout << gcd << " " << x << " " << y << std::endl;
|
||||
extendedEuclid_1(a, b, &gcd, &x, &y);
|
||||
std::cout << gcd << " " << x << " " << y << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user