egcd.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #include "egcd.h"
  2. /*Computes the coefficients of the smallest positive linear combination of two
  3. integers _a and _b.
  4. These are a solution (u,v) to the equation _a*u+_b*v==gcd(_a,_b).
  5. _a: The first integer of which to compute the extended gcd.
  6. _b: The second integer of which to compute the extended gcd.
  7. _u: Returns the coefficient of _a in the smallest positive linear
  8. combination.
  9. _v: Returns the coefficient _of b in the smallest positive linear
  10. combination.
  11. Return: The non-negative gcd of _a and _b.
  12. If _a and _b are both 0, then 0 is returned, though in reality the
  13. gcd is undefined, as any integer, no matter how large, will divide 0
  14. evenly.
  15. _a*u+_b*v will not be positive in this case.
  16. Note that the solution (u,v) of _a*u+_b*v==gcd(_a,_b) returned is not
  17. unique.
  18. (u+(_b/gcd(_a,_b))*k,v-(_a/gcd(_a,_b))*k) is also a solution for all
  19. k.
  20. The coefficients (u,v) might not be positive.*/
  21. int egcd(int _a,int _b,int *_u,int *_v){
  22. int a;
  23. int b;
  24. int s;
  25. int t;
  26. int u;
  27. int v;
  28. /*Make both arguments non-negative.
  29. This forces the return value to be non-negative.*/
  30. a=_a<0?-_a:_a;
  31. b=_b<0?-_b:_b;
  32. /*Simply use the extended Euclidean algorithm.*/
  33. s=v=0;
  34. t=u=1;
  35. while(b){
  36. int q;
  37. int r;
  38. int w;
  39. q=a/b;
  40. r=a%b;
  41. a=b;
  42. b=r;
  43. w=s;
  44. s=u-q*s;
  45. u=w;
  46. w=t;
  47. t=v-q*t;
  48. v=w;
  49. }
  50. /*u and v were computed for non-negative a and b.
  51. If the arguments passed in were negative, flip the sign.*/
  52. *_u=_a<0?-u:u;
  53. *_v=_b<0?-v:v;
  54. return a;
  55. }