测试环境为linux下,假设在默认路径下(/usr/local)装好了NTL,则编写好相应的test.cpp文件后执行:g++ -g -O2 test.cpp -o test -lntl -lgmp -lm
(1)使用大整数类 ZZ :
例1: 计算
#include <NTL/ZZ.h>
using namespace std;
using namespace NTL;
int main()
{
ZZ a, b, c;
cin >> a;
cin >> b;
c = (a+1)*(b+1);
cout << c << "\n";
}
例2:从标准输入中读取一个整数列表,计算他们的平方和
(测试中循环结束的条件是输入不满足要求的字符(非整数)或者按’ctrl’+’D’)
#include <NTL/ZZ.h>
using namespace std;
using namespace NTL;
int main()
{
ZZ acc, val;
acc = 0;
while (cin >> val)
acc += val*val;
cout << acc << "\n";
}
例3: 模幂运算 (a^e mod n)
注:对于NTL中的每一个函数,有一个 procedural version,它将结果存储在第一个参数中,这样不会创建任何临时对象。
ZZ PowerMod(const ZZ& a, const ZZ& e, const ZZ& n)
{
if (e == 0)
return ZZ(1);
long k = NumBits(e);
ZZ res;
res = 1;
for (long i = k-1; i >= 0; i--){
// res = (res*res) % n;
res = SqrMod(res, n);
if (bit(e,i) == 1) //如果e的第i位为1
// res = (res*a) % n;
MulMod(res, res, a, n);
}
if (e < 0)
return InvMod(res,n);
else
return res;
}
例4:以下程序提示用户输入,并应用简单的概率素性测试。在NTL中已经提供了一个稍复杂的素性测试!
注:使用Miller-Rabin素数测试。
#include <NTL/ZZ.h>
using namespace std;
using namespace NTL;
long witness(const ZZ& n, const ZZ& x) //n为素数候选者,x为随机数
{
ZZ m, y, z;
long j, k;
if (x == 0) return 0;
// compute m, k such that n-1 = 2^k * m, m odd:
k = 1;
m = n/2;
while (m % 2 == 0) {
k++;
m /= 2;
}
/*计算m,k的代码可以改写为:
k = 1;
m = n >> 1;
while (!IsOdd(m)){
k++;
m >>= 1;
}
*/
/*或者改写为:
k = 1;
while (bit(n, k) == 0) k++;
m = n >> k;
*/
/*在NTL内置的函数中,有一个刚好满足我们的要求:
m = n - 1;
k = MakeOdd(m);
*/
z = PowerMod(x, m, n); // z = x^m % n
if (z == 1) return 0;
j = 0;
do {
y = z;
z = (y*y) % n;
j++;
} while (j < k && z != 1);
return z != 1 || y != n-1;
}
long PrimeTest(const ZZ& n, long t)
{
if (n <= 1) return 0;
// first, perform trial division by primes up to 2000
PrimeSeq s; // a class for quickly generating primes in sequence
long p;
p = s.next(); // first prime is always 2
while (p && p < 2000) {
if ((n % p) == 0) return (n == p);
p = s.next();
}
// second, perform t Miller-Rabin tests
ZZ x;
long i;
for (i = 0; i < t; i++) {
x = RandomBnd(n); // random number between 0 and n-1
if (witness(n, x))
return 0;
}
return 1;
}
int main()
{
ZZ n;
cout << "n: ";
cin >> n;
if (PrimeTest(n, 10))
cout << n << " is probably prime\n";
else
cout << n << " is composite\n";
}
参考资料:
http://www.shoup.net/ntl/doc/tour-ex1.html
http://www.shoup.net/ntl/doc/ZZ.cpp.html