@@ -25,6 +25,45 @@ namespace math {
25
25
* implementation.
26
26
*/
27
27
namespace ncr_modulo_p {
28
+
29
+ namespace utils {
30
+ /* * Finds the value of x, y such that a*x + b*y = gcd(a,b)
31
+ *
32
+ * @params[in] the numbers 'a', 'b' and address of 'x' and 'y' from above
33
+ * equation
34
+ * @returns the gcd of a and b
35
+ */
36
+ uint64_t gcdExtended (const uint64_t & a, const uint64_t & b, int64_t * x,
37
+ int64_t * y) {
38
+ if (a == 0 ) {
39
+ *x = 0 , *y = 1 ;
40
+ return b;
41
+ }
42
+
43
+ int64_t x1 = 0 , y1 = 0 ;
44
+ uint64_t gcd = gcdExtended (b % a, a, &x1, &y1);
45
+
46
+ *x = y1 - (b / a) * x1;
47
+ *y = x1;
48
+ return gcd;
49
+ }
50
+
51
+ /* * Find modular inverse of a with m i.e. a number x such that (a*x)%m = 1
52
+ *
53
+ * @params[in] the numbers 'a' and 'm' from above equation
54
+ * @returns the modular inverse of a
55
+ */
56
+ int64_t modInverse (const uint64_t & a, const uint64_t & m) {
57
+ int64_t x = 0 , y = 0 ;
58
+ uint64_t g = gcdExtended (a, m, &x, &y);
59
+ if (g != 1 ) { // modular inverse doesn't exist
60
+ return -1 ;
61
+ } else {
62
+ int64_t res = ((x + m) % m);
63
+ return res;
64
+ }
65
+ }
66
+ }; // namespace utils
28
67
/* *
29
68
* @brief Class which contains all methods required for calculating nCr mod p
30
69
*/
@@ -47,43 +86,6 @@ class NCRModuloP {
47
86
}
48
87
}
49
88
50
- /* * Finds the value of x, y such that a*x + b*y = gcd(a,b)
51
- *
52
- * @params[in] the numbers 'a', 'b' and address of 'x' and 'y' from above
53
- * equation
54
- * @returns the gcd of a and b
55
- */
56
- uint64_t gcdExtended (const uint64_t & a, const uint64_t & b, int64_t * x,
57
- int64_t * y) {
58
- if (a == 0 ) {
59
- *x = 0 , *y = 1 ;
60
- return b;
61
- }
62
-
63
- int64_t x1 = 0 , y1 = 0 ;
64
- uint64_t gcd = gcdExtended (b % a, a, &x1, &y1);
65
-
66
- *x = y1 - (b / a) * x1;
67
- *y = x1;
68
- return gcd;
69
- }
70
-
71
- /* * Find modular inverse of a with m i.e. a number x such that (a*x)%m = 1
72
- *
73
- * @params[in] the numbers 'a' and 'm' from above equation
74
- * @returns the modular inverse of a
75
- */
76
- int64_t modInverse (const uint64_t & a, const uint64_t & m) {
77
- int64_t x = 0 , y = 0 ;
78
- uint64_t g = gcdExtended (a, m, &x, &y);
79
- if (g != 1 ) { // modular inverse doesn't exist
80
- return -1 ;
81
- } else {
82
- int64_t res = ((x + m) % m);
83
- return res;
84
- }
85
- }
86
-
87
89
/* * Find nCr % p
88
90
*
89
91
* @params[in] the numbers 'n', 'r' and 'p'
@@ -101,11 +103,11 @@ class NCRModuloP {
101
103
return 1 ;
102
104
}
103
105
// fac is a global array with fac[r] = (r! % p)
104
- int64_t denominator = modInverse (fac[r], p);
106
+ int64_t denominator = utils:: modInverse (fac[r], p);
105
107
if (denominator < 0 ) { // modular inverse doesn't exist
106
108
return -1 ;
107
109
}
108
- denominator = (denominator * modInverse (fac[n - r], p)) % p;
110
+ denominator = (denominator * utils:: modInverse (fac[n - r], p)) % p;
109
111
if (denominator < 0 ) { // modular inverse doesn't exist
110
112
return -1 ;
111
113
}
0 commit comments