-
Notifications
You must be signed in to change notification settings - Fork 273
/
Copy pathbigint-func.cc
113 lines (98 loc) · 1.66 KB
/
bigint-func.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// $Id: bigint-func.cc,v 1.1.1.1 2002-06-13 22:00:30 kroening Exp $
// Author: Dirk Zoller
// References:
//
// [1] Hüttenhofer/Lesch/Peyerimhoff, Mathematik in Anwendung mit C++
// Heidelberg, Wiesbaden 1994
#include "bigint.hh"
BigInt pow(BigInt const &x, std::size_t y)
{
BigInt a = x;
BigInt r = 1;
for (;;)
{
if (y & 1)
r *= a;
y >>= 1;
if (y == 0)
return r;
a *= a;
}
}
// Modular exponentiation, see [1] p. 74.
BigInt
pow (BigInt const &x, BigInt const &y, BigInt const &m)
{
BigInt a = x;
BigInt b = y;
BigInt r = 1;
for (;;)
{
a %= m;
if (b.is_odd())
{
r *= a;
r %= m;
}
b /= 2;
if (b.is_zero())
return r;
a *= a;
}
}
// Integer square root. see [1] p.23, slightly changed for better performance.
BigInt
sqrt (BigInt const &n)
{
BigInt x0 = n;
BigInt x1 = n;
x1 += 1;
x1 /= 2;
while (x1 < x0)
{
x0 = x1;
x1 += n / x0;
x1 /= 2;
}
return x0;
}
BigInt
gcd (const BigInt &X, const BigInt &Y)
{
BigInt x (X);
BigInt y (Y);
for (;;)
{
if (y.is_zero())
return x;
x %= y;
if (x.is_zero())
return y;
y %= x;
}
}
// Modular inverse, see [1] p.35
// Returns i in range 1..m-1 such that i*a = 1 mod m.
// a must be in range 1..m-1.
BigInt
modinv (const BigInt &a, const BigInt &m)
{
BigInt j (1), i (0);
BigInt b (m), c (a);
BigInt x, y;
while (!c.is_zero())
{
BigInt::div (b, c, x, y);
b = c;
c = y;
y = j;
// j = i - j * x; trading clarity for efficiency.
j *= x;
j -= i;
j.negate();
i = y;
}
if (i.is_negative())
i += m;
return i;
}