NTL使用教程1(Big Integers)

测试环境为linux下,假设在默认路径下(/usr/local)装好了NTL,则编写好相应的test.cpp文件后执行:g++ -g -O2 test.cpp -o test -lntl -lgmp -lm

(1)使用大整数类 ZZ :
例1: 计算 c=(a+1)(b+1) c = ( a + 1 ) ∗ ( b + 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

  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值