大数模幂运算快速算法

合集下载

快速幂取模算法详解

快速幂取模算法详解

快速幂取模算法详解转载https:///ltyqljhwcm/article/details/53043646 article>1.⼤数模幂运算的缺陷:快速幂取模算法的引⼊是从⼤数的⼩数取模的朴素算法的局限性所提出的,在朴素的⽅法中我们计算⼀个数⽐如5^1003%31是⾮常消耗我们的计算资源的,在整个计算过程中最⿇烦的就是我们的5^1003这个过程缺点1:在我们在之后计算指数的过程中,计算的数字不都拿得增⼤,⾮常的占⽤我们的计算资源(主要是时间,还有空间)缺点2:我们计算的中间过程数字⼤的恐怖,我们现有的计算机是没有办法记录这么长的数据的,所以说我们必须要想⼀个更加⾼效的⽅法来解决这个问题2.快速幂的引⼊:我们⾸先从优化的过程开始⼀步⼀步优化我们的模幂算法1.朴素模幂运算过程:1. #define ans=12. for(int i=1;i<=b;i++)3. {4. ans*=a;5. }根据我们上⾯说的,这种算法是⾮常的⽆法容忍的,我们在计算的过程中出现的两个缺点在这⾥都有体现在这⾥我们如果要做优化的话,我肥就是每个过程中都加⼀次模运算,但是我们⾸先要记住模运算是⾮常的消耗内存资源的,在计算的次数⾮常的⼤的时候,我们是没有办法忍受这种时间耗费的2.快速幂引⼊:在讲解快速幂取模算法之前,我们先将⼏个必备的知识1.对于取模运算:(a*b)%c=(a%c)*(b%c)%c这个是成⽴的:也是我们实现快速幂的基础之后我们来看看快速幂的核⼼本质我通过离散课上的学习,将快速幂的本质差不多理解了⼀下,感觉还是很深刻的在这⾥,我们对指数懂了⼀些⼿脚,核⼼思想在于将⼤数的幂运算拆解成了相对应的乘法运算,利⽤上⾯的式⼦,始终将我们的运算的数据量控制在c的范围以下,这样我们可以客服朴素的算法的缺点⼆,我们将计算的数据量压缩了很⼤⼀部分,当指数⾮常⼤的时候这个优化是更加显著的,我们⽤Python来做⼀个实验来看看就知道我们优化的效率有多⾼了1. from time import *2. def orginal_algorithm(a,b,c): #a^b%c3. ans=14. a=a%c #预处理,防⽌出现a⽐c⼤的情况5. for i in range(b):6. ans=(ans*a)%c7. return ans8.9. def quick_algorithm(a,b,c):10. a=a%c11. ans=112. #这⾥我们不需要考虑b<0,因为分数没有取模运算13. while b!=0:14. if b&1:15. ans=(ans*a)%c16. b>>=117. a=(a*a)%c18. return ans19.20. time=clock()21. a=eval(input(“底数:”))22. b=eval(input(“指数:”))23. c=eval(input(“模:”))24. print(“朴素算法结果%d”%(orginal_algorithm(a,b,c)))25. print(“朴素算法耗时:%f”%(clock()-time))26. time=clock()27. print(“快速幂算法结果%d”%(quick_algorithm(a,b,c)))28. print(“快速幂算法耗时:%f”%(clock()-time))实验结果:4. 朴素算法结果55. 朴素算法耗时:3.2899526. 快速幂算法结果57. 快速幂算法耗时:0.006706我们现在知道了快速幂取模算法的强⼤了,我们现在来看核⼼原理:1. 对于任何⼀个整数的模幂运算2. a^b%c3. 对于b我们可以拆成⼆进制的形式4. b=b0+b1*2+b2*2^2+…+bn*2^n5. 这⾥我们的b0对应的是b⼆进制的第⼀位6. 那么我们的a^b运算就可以拆解成7. a^b0*a^b1*2*…*a^(bn*2^n)8. 对于b来说,⼆进制位不是0就是1,那么对于bx为0的项我们的计算结果是1就不⽤考虑了,我们真正想要的其实是b的⾮0⼆进制位9.10. 那么假设除去了b的0的⼆进制位之后我们得到的式⼦是11. a^(bx*2^x)*…*a(bn*2^n)12. 这⾥我们再应⽤我们⼀开始提到的公式,那么我们的a^b%c运算就可以转化为13. (a^(bx*2^x)%c)*…*(a^(bn*2^n)%c)14. 这样的话,我们就很接近快速幂的本质了1. (a^(bx*2^x)%c)*…*(a^(bn*2^n)%c)2. 我们会发现令3. A1=(a^(bx*2^x)%c)4. …5. An=(a^(bn*2^n)%c)6. 这样的话,An始终是A(n-1)的平⽅倍(当然加进去了取模匀速那),依次递推现在,我们基本的内容都已经了解到了,现在我们来考虑实现它:1. int quick(int a,int b,int c)2. {3. int ans=1; //记录结果4. a=a%c; //预处理,使得a处于c的数据范围之下5. while(b!=0)6. {7. if(b&1) ans=(ans*a)%c; //如果b的⼆进制位不是0,那么我们的结果是要参与运算的8. b>>=1; //⼆进制的移位操作,相当于每次除以2,⽤⼆进制看,就是我们不断的遍历b的⼆进制位9. a=(a*a)%c; //不断的加倍10. }11. return ans;12. }现在,我们的快速幂已经讲完了我们来⼤致的推演⼀下快速幂取模算法的时间复杂度⾸先,我们会观察到,我们每次都是将b的规模缩⼩了2倍那么很显然,原本的朴素的时间复杂度是O(n)快速幂的时间复杂度就是O(logn)⽆限接近常熟的时间复杂度⽆疑逼朴素的时间复杂度优秀很多,在数据量越⼤的时候,者中优化效果越明显3.OJ例题POJ1995题意:快速幂版题1. #include“iostream”2. #include“cstdio”3. #include“cstring”4. #include“cstdlib”5.6. using namespace std;7.8. int ans=0;9. int a,b;10. int c;11.12. int quick(int a,int b,int c)13. {14. int ans=1;15. a=a%c;16. while(b!=0)17. {18. if(b&1) ans=(ans*a)%c;19. b>>=1;20. a=(a*a)%c;24.25. int main()26. {27. int for_;28. int t;29. scanf(“%d”,&t);30. while(t–)31. {32. ans=0;33. scanf(“%d%d”,&c,&for_);34. for(int i=1;i<=for_;i++)35. {36. scanf(“%d%d”,&a,&b);37. ans=(ans+quick(a,b,c))%c;38. }39. printf(“%d\n”,ans);40. }41. return 0;42. }</div></div></article>。

mod n大数幂乘的快速算法

mod n大数幂乘的快速算法

mod n大数幂乘的快速算法
快速幂乘算法利用了指数的二进制表示方式来加速计算。

具体算法如下:
1. 初始化结果为1:result = 1
2. 将指数按二进制拆分为若干个二次幂:将指数n转换为二进制表示形式,例如n=13,二进制表示为1101,可以拆分为
2^0、2^2、2^3。

3. 从最低位开始遍历二进制位:
- 若当前位为1,则计算当前二次幂的乘积并累乘到结果中:result *= base^(2^i),其中base为底数,i为当前二进制位位置。

- 若当前位为0,则不做处理。

4. 返回结果。

例如,计算2^13的值:
拆分指数为2^0、2^2、2^3,可以得到2^13 = 2^0 * 2^2 * 2^3
= 2 * 4 * 8 = 128。

Python代码示例:
```python
def power(base, n):
result = 1
# 将指数n转换为二进制表示形式
binary_n = bin(n)[2:]
# 从最低位开始遍历二进制位
for i in range(len(binary_n)):
# 若当前位为1,则计算当前二次幂的乘积并累乘到结果中
if binary_n[i] == '1':
result *= base ** (2 ** i)
return result
# 测试
print(power(2, 13)) # 输出:128
```
快速幂乘算法的时间复杂度为O(logn),比普通的循环累乘要更高效。

该算法在计算大数的幂乘时特别有效,能够减少计算次数,提高计算速度。

幂的快速计算方法

幂的快速计算方法

幂的快速计算方法嘿,朋友们!今天咱来聊聊幂的快速计算方法,这可真是个超有用的本事呢!咱先从简单的例子说起哈。

比如 2 的 3 次方,那就是 2×2×2,等于8 呗。

可要是数字大一点,次方数高一点,那靠这样一个一个乘可得费老劲了。

咱可以找规律呀!就像玩游戏找通关秘籍一样。

比如说,2 的 4 次方,不就是 2 的 3 次方再乘个 2 嘛,那就是 8×2 等于 16 呀。

这就有点门道了吧!再比如 10 的几次方,这就更好玩啦。

10 的 2 次方就是 100,10 的3 次方就是 1000,你瞧,多简单明了!那 10 的4 次方不就是在 1000后面加个 0 嘛,这不是手到擒来嘛!还有哦,同底数幂相乘,底数不变指数相加,这可是个大宝贝呀!就像搭积木一样,把小的凑成大的。

比如说 2 的 3 次方乘 2 的 4 次方,那不就是 2 的 7 次方嘛。

那要是遇到除法呢?嘿,也有招!同底数幂相除,底数不变指数相减。

这就像分糖果一样,按比例来分。

咱再说说负数次方。

哎呀呀,这可别被吓到啦!负数次方就相当于求倒数的正数次方。

比如说 2 的负 3 次方,不就是 1 除以 2 的 3 次方嘛,算起来也不难呀。

想象一下,要是你掌握了这些方法,那算幂的时候不就跟玩儿似的,唰唰几下就出来了,多牛啊!其实呀,数学里好多东西就跟生活中的小窍门一样,找到了就特别好使。

幂的计算方法也是,一旦你掌握了,那在数学的世界里就能畅游啦!所以啊,大家可别小瞧了这幂的快速计算方法,它能让你的数学之路走得更顺畅呢!别再死记硬背啦,多找找规律,多玩玩这些数字游戏,你会发现数学的乐趣无穷大呀!就这么去试试吧,相信你会有大收获的!加油哦!。

快速模幂算法范文

快速模幂算法范文

快速模幂算法范文下面我们将详细介绍快速模幂算法的原理和步骤。

1.原理:假设要计算 a^b mod c 的值,其中 a 是底数,b 是指数,c 是模数。

快速模幂算法的基本思想是将指数 b 进行二进制拆分,然后利用二进制的运算特性进行迭代计算。

2.步骤:-将指数b转换为二进制形式。

例如,b=13(1101)。

- 初始化两个变量:result=1 作为最终结果的累积值,和 base=a作为当前底数。

- 从二进制数的最低位开始,如果最低位是1,则将当前底数乘以result,并对结果取模 c。

例如,result = 1 * a = a mod c。

- 将当前底数进行平方运算,并对结果取模 c,base = a^2 mod c。

-将指数b右移一位,相当于b=b/2-重复上述步骤,直到指数b的所有位都被处理完毕。

- 返回结果 result。

3.例子:让我们以a=3,b=13,c=7为例进行演示。

-将指数b的二进制表示为1101- 初始化 result=1,base=3- 最低位为1,将当前底数乘以 result,并对结果取模 c,result = 1 * 3 = 3 mod 7- 进行平方运算,base = 3^2 mod 7 = 9 mod 7 = 2 mod 7-右移一位,b=110。

-最低位为0,不进行计算。

- 进行平方运算,base = 2^2 mod 7 = 4 mod 7-右移一位,b=11- 最低位为1,将当前底数乘以 result,并对结果取模 c,result = 3 * 4 = 12 mod 7- 进行平方运算,base = 4^2 mod 7 = 16 mod 7 = 2 mod 7-右移一位,b=1- 最低位为1,将当前底数乘以 result,并对结果取模 c,result = 12 * 2 = 24 mod 7 = 3 mod 7- 进行平方运算,base = 2^2 mod 7 = 4 mod 7-右移一位,b=0。

大数模幂运算快速算法概要

大数模幂运算快速算法概要

有朋友问我的博文《素性测试》中的 Miller-Rabin 算法的大数模幂运算快速算法怎么理解,由于在《素性测试》中没有讲解算法原理,所以在此单独一个篇文章详细讲这个算法。

这是一个在密码学中比较重要的算法,在我的《素性测试》一文则是用于实现费马小定理。

首先我们先把问题简化一下,看看如何快速求 a^b.先看看我们熟知的两个数学公式:a^(2c = (a^c^2;a^(2c+1 = a*((a^c^2;我们就利用这两个数学公式来解决这个问题,比如 a=3,b=13时,我们把 b 写成二进制的形式 13(10=1101(2, 我们从低位到高位运算,每运算一位可以将 b 右移一位,上面的例子可以转化成 3^13 = 3^1 * 3^4 * 3^8, 结合上面的两个数学公式我们可以写出如下的代码:代码清单:[java]view plaincopy如上面的叙述叙述中可以看出快速 pow 算法的时间复杂度取决于 b 的二进制位数 ,而传统的一位一位累乘的 pow 算法的时间复杂度取决于 b 的大小 ,例如上述例子中,两种算法的运算次数分别为 4次,和 13次。

随着 b 的增大,效率上的差距是显然的。

下面进入我们的主题 ---大数模幂运算快速算法 (a^b % m要计算这个,我们首先还要知道一个数学公式:a^b % m = (...((a % m * a % m ......* a % m其中 a%m有 b 个下面我还用上面 b=13的例子,利用这个公式来证明下a^13 % m = ((a^8 % m * ((a^4 % m * ((a^1 % m证明:由 a^b % m = (...((a % m * a % m ......* a % m其中 a%m有 b 个得a^8 % m = (...((a % m * a % m ......* a % m其中 a%m有 8个a^4 % m = (...((a % m * a % m ......* a % m其中 a%m有 4个a^1 % m = (...((a % m * a % m ......* a % m 其中 a%m有 1个所以 ((a^8 % m * ((a^4 % m * ((a^1 % m = (...((a % m * a % m ......* a % m 其中a%m有 13个 = a^13 % m ;证毕。

幂运算常用的8个公式幂数口诀

幂运算常用的8个公式幂数口诀

幂运算常用的8个公式幂数口诀幂运算常用的8个公式是:1、同底数幂相乘;2、幂的乘方;3、积的乘方;4、同底数幂相除;5、a^(m+n)=a^m·a^n;6、a^mn=(a^m)·n;7、a^m·b^m=(ab)^m;8、a^(m-n)=a^m÷a^n(a≠0)。

幂运算常用的8个公式幂运算常用的8个公式是:1、同底数幂相乘:a^m·a^n=a^(m+n)。

2、幂的乘方:(a^m)n=a^mn。

3、积的乘方:(ab)^m=a^m·b^m。

4、同底数幂相除:a^m÷a^n=a^(m-n)(a≠0)。

5、a^(m+n)=a^m·a^n。

6、a^mn=(a^m)·n。

7、a^m·b^m=(ab)^m。

8、a^(m-n)=a^m÷a^n(a≠0)。

幂数口诀指数加减底不变,同底数幂相乘除。

指数相乘底不变,幂的乘方要清楚。

积商乘方原指数,换底乘方再乘除。

非零数的零次幂,常值为1不糊涂。

负整数的指数幂,指数转正求倒数。

看到分数指数幂,想到底数必非负。

乘方指数是分子,根指数要当分母。

幂运算是什么意思1、幂运算是一种关于幂的数学运算。

掌握正整数幂的运算性质(同底数幂的乘法、幂的乘方、积的乘方、同底数幂的除法),能用字母式子和文字语言正确地表述这些性质,并能运用它们熟练地进行运算。

2、思考对于数学的学习是最核心的,对做题更是如此。

数学是考你对知识点的运用,能够理解这些知识点,然后解题,通过解题巩固所学知识。

一开始不会解题,要忍住不去翻看答案,自己先思考。

3、在学习法则的过程中,不是简单地套用公式,而是除了理解法则的形成过程外,还需要知道每一个法则的具体适用情况,并会变式和引申。

在运用幂的运算法则进行计算时,一定要审清题,特别注意系数、符号和指数,其次要正确运用公式,看清底数和指数的变化,学会用转化的方法和整体的思想去解决问题。

快速幂算法——精选推荐

快速幂算法——精选推荐

快速幂算法快速幂算法1. 问题 -- 求2100的后三位数思路1 : 直接for循环求解 求出2的100次⽅再%1000即为后三位数 时间复杂度O(n)// base 底数 index 指数long long Pow(long long base, long long index) {int res = 1;for (int i = 0; i < index; i++) {res = res * base;}return res;}int main(){cout << Pow(2, 100) % 1000;return 0;}结果为0原因: 由于指数爆炸2的100次⽅会是⼀个⾮常⼤的数 我们所学的编程语⾔中没有数据类型能承受如此之⼤的数 所以产⽣了溢出解决办法 利⽤模运算法则2. “取模”运算的运算法则(a + b) % p = (a % p + b % p) % p (1)(a - b) % p = (a % p - b % p ) % p (2)(a * b) % p = (a % p * b % p) % p (3)(a^b) % p = ((a % p)^b) % p (4)我们只需要关注第3条法则 (a * b) % p = (a % p * b % p) % p推导过程:根据上⾯的推导过程 可以推导出(a * b * c) % p = (a % p * b % p * c % p) % p所以 (a * b * c * d * ......) = (a % p * b % p * c % p * d % p * ......) % p所以,借助这个法则,只需要在循环乘积的每⼀步都提前进⾏“取模”运算// base 底数 index 指数int Pow(int base, int index) {int res = 1;for (int i = 0; i < index; i++) {// 1 * 2 % 1000 * 2 % 1000 * ......res = res * base;res = res % 1000;}return res % 1000;}int main(){cout << Pow(2, 100);return 0;}结果 : 376 时间复杂度依旧为O(n) 所以当指数很⼤时运算需要很长时间 所以需要⽤到快速幂3.快速幂快速幂算法的核⼼思想是⼆分法: 每次都将指数/2 底数求平⽅平⽅310 = 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 需要10次运算将其对半分解310 = 3^10=(3 * 3) * (3 * 3) * (3 * 3) * (3 * 3) * (3 * 3) = (32)5 = 95此时需要 5次运算但此时指数为奇数⽆法整除2 所以将其分解为95 = 94 * 91对94继续进⾏分解95 = (9 * 9) * (9 * 9) * 9 = (92)2 * 9 = (81)2 * 9对812进⾏分解95 = (81 * 81)1 * 9 = 65611 * 9此时指数⼜为奇数但⽆法对指数进⾏压缩操作将上述流程转化为代码:long long Pow(long long base, long long index) {long long res = 1;while (index) {if (index % 2 != 0) { // 指数为奇数// 拆成A^1 和 A^(n - 1)res *= base;// 指数减⼀由于编程语⾔中默认向下取整所以index--可以不写//index--;}// 到这说明指数为偶数底数平⽅base *= base;// 指数减半index /= 2;}return res;}转化为上题代码long long Pow(long long base, long long index) {long long res = 1;while (index) {if (index % 2 != 0) {res = res * base % 1000;}base = (base * base) % 1000;index /= 2;}return res % 1000;}4.位运算优化判断⼀个数是奇数还是偶数可⽤位运算 如果⼀个数 a&1 == 0 则这个数为偶数 == 1 为奇数⼀个整数右移⼀位等于该数除以2a>>1 == a / 2long long Pow(long long base, long long index) {long long res = 1;while (index) {if (index&1) {res = res * base % 1000;index--;}base = (base * base) % 1000;index >>= 1;}return res % 1000;}。

幂模运算快速算法

幂模运算快速算法

幂模运算快速算法——滑动窗口算法设e 的二进制表达式为:∑-==10)2(k i i i e e ,其中}1,0{∈i e 。

那么,n X e mod 的幂模运算二进制算法如下:输入:X ,e ,n输出:n X C emod =Step 1: 1=CStep 2: for 1-=k i downto 0Step 2.1: n C C C mod )*(=Step 2.2: if 1=i e then n X C C mod )*(=Step 3: return C由二进制法的计算过程可知:当指数e 的二进制位为0时,会减少乘模的次数。

二进制法的直接推广是m 进制法,其基本思想是把指数分成r bits(即m 2log bits)的数据块,每次取指数e 的r bits 进行运算,从而使整个幂模运算的效率提高。

假定e 的每个比特是0或1的概率相同,则m 进制法一个数据块是全0的可能性为r -2,当r 增加时,数据块为全0的可能性会减少,因此在Step 2.2需做乘模的可能性增加;而当r 减小时,算法总的乘模次数也会增加。

滑动窗口技术提供了一种折衷,允许零数据块和非零数据块是变长的,目的是增加全0数据块的数量,从而使总的乘模次数减少。

具体方法是:把k bits 指数分解成z 个零窗口或非零窗口i F ,i F 长度为)(i F L 。

规定最大窗口长度为d ,即))(max(i F L d =,显然总窗口数z 可能不等于d k 。

d 的取值与模数的位长有关。

对单一窗口的幂模运算进行预处理,即预计算n X w mod ,其中12,,7,5,3-=d w ,因为指数分解的原则使非零窗口的最低有效位必定为1,故w 为为奇数,从而使预处理次数减少了一半。

滑动窗口算法处理幂模运算的过程如下:输入:X ,e ,n输出:n X C e mod =Step 1: 预计算。

Step 2: 将k bits 的指数e 分解成长度为)(i F L 的零窗口或非零窗口i F ,1,,2,1,0-=z i 。

快速幂算法求a的n次方

快速幂算法求a的n次方

快速幂算法求a的n次方1. 引言快速幂算法(Fast Power Algorithm)是一种用于求解幂运算的高效算法。

在计算机科学和数学领域中,幂运算是一种常见的运算,例如计算一个数的n次方。

传统的幂运算算法时间复杂度较高,而快速幂算法通过巧妙地利用数学性质,能够大大提高计算效率。

本文将介绍快速幂算法的原理及实现方法,并给出相应的代码示例。

同时,还将讨论该算法的时间复杂度和应用场景,以便读者更好地理解和应用快速幂算法。

2. 快速幂算法原理快速幂算法的核心思想是利用指数的二进制表示来加速幂运算。

对于一个数a的n 次方,可以将n表示为二进制形式,例如n=101101,那么a的n次方可以表示为a(20) * a(22) * a(23) * a(25)。

观察上述表达式,可以发现,a的n次方可以通过连续平方和累乘的方式得到。

具体步骤如下:1.将指数n转化为二进制形式,并倒序排列;2.从低位到高位遍历二进制数,如果当前位为1,则将a进行平方,并与结果累乘;3.每次遍历完当前位,将底数a进行平方,用于下一位的计算。

通过以上步骤,就可以得到a的n次方的结果。

3. 快速幂算法实现下面给出使用Python语言实现快速幂算法的代码示例:def fast_power(a, n):result = 1while n > 0:if n % 2 == 1:result *= aa *= an //= 2return result在上述代码中,a表示底数,n表示指数。

首先,初始化结果为1。

然后,通过循环遍历指数的二进制形式,如果当前位为1,则将底数平方并与结果累乘,每次遍历完当前位,将底数平方用于下一位的计算。

最后,返回结果。

4. 时间复杂度分析快速幂算法的时间复杂度为O(log n),其中n为指数的大小。

这是因为在每一次循环中,指数n都会减少一半,直到减少为0。

相比之下,传统的幂运算算法的时间复杂度为O(n),即需要执行n次乘法操作。

快速幂算法

快速幂算法

快速幂取余
所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余)。

在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快、计算范围更大的算法,产生了快速幂取模算法。

应用的公式:
d=a b mod n=(…((((a mod n)*a)mod n)*a)mod n…*a)mod n {共b个a}
(a × b) mod c=( (a mod c) × b) mod c.
1.有三根杆子A,B,C。

A杆上有3N个(N>1)穿孔圆盘,共有N个不同的大小,每个尺寸都有三个完全相同的圆盘,盘的尺寸由下到上依次变小。

要求按下列规则将所有圆盘移至C 杆:
1.每次只能移动一个圆盘;
2.大盘不能叠在小盘上面。

模运算——大整数取模、幂取模等

模运算——大整数取模、幂取模等

3 int m;
Hale Waihona Puke 45 int biginteger_mod(char* n, int m)
6{
7 int len = strlen(n);
8 int ans = 0;
9 for(int i = 0;i < len;i++)
10
ans = (int)(((long long)ans * 10 + n[i] - '0') % m);
a %= p; b %= p; return (a - b + p) % p; }
//a mod n可能小于b mod n,需要在结果加上n
LL mul_mod(LL a, LL b, LL p) {
a %= p; b %= p; return a * b % p; //a mod n和b mod n的乘积可能超LL }
二、大整数取模
求n mod m 的值,(n ≤10100,m ≤109) 思路:首先,将大整数根据秦九韶公式写成“自左向右”的形式:4351 = ((4 * 10 + 3) * 10 + 5) * 10 + 1,然后利用模的性质,逐步取模。
1 const int maxn = 100 + 10;
2 char n[maxn];
11 return ans;
12 }
三、幂取模
直接暴力写是O(n),较快的方法是分治法,时间复杂度是O(logn)
求an mod m 的值,
1 LL pow_mod(LL a, LL n, LL m) 2{ 3 if (n == 0) return 1; 4 LL ans = pow_mod(a, n / 2, m); 5 ans = ans * ans % m; 6 if (n % 2) ans = ans * a % m; 7 return ans; 8}

幂的运算的技巧

幂的运算的技巧

幂的运算的技巧幂的运算技巧是在数学中非常重要的一个概念。

幂运算是指我们将一个数称为底数,对其进行多次乘法运算的操作。

在幂运算中,底数表示被乘的数,指数表示乘法的次数,结果表示乘法的积。

在幂运算中,存在一些基本的运算规则和技巧,可以帮助我们简化计算,提高效率。

下面详细介绍一些常见的幂运算技巧。

1. 幂的乘法法则:a^m * a^n = a^(m+n)这个法则说明了两个相同底数的幂相乘的结果是将指数相加。

例如,2^3 * 2^4 = 2^(3+4) = 2^7 = 128。

2. 幂的除法法则:a^m / a^n = a^(m-n)这个法则说明了两个相同底数的幂相除的结果是将指数相减。

例如,2^7 / 2^4 = 2^(7-4) = 2^3 = 8。

3. 幂的零指数法则:a^0 = 1这个法则说明了任何数的零指数的幂等于1。

例如,2^0 = 1。

4. 幂的负指数法则:a^(-n) = 1 / a^n这个法则说明了一个数的负指数可以转化为其倒数的正指数。

例如,2^(-3) = 1 / 2^3 = 1/8。

5. 幂的乘方法则:(a^m)^n = a^(m*n)这个法则说明了一个指数数的幂的结果等于将两个指数相乘。

例如,(2^3)^4 = 2^(3*4) = 2^12 = 4096。

6. 幂的分布法则:a^(m+n) = a^m * a^n这个法则说明了一个幂的和等于将两个指数分别进行幂运算后相乘。

例如,2^(3+4) = 2^3 * 2^4 = 8 * 16 = 128。

7. 幂的幂法则:(a^m)^n = a^(m*n)这个法则说明了一个幂的指数数再进行幂运算后的结果就是将两个指数相乘。

例如,(2^3)^4 = 2^(3*4) = 2^12 = 4096。

8. 幂的整数指数法则:(a*b)^n = a^n * b^n这个法则说明了两个数的乘积的指数等于将每一个因子的指数分别进行幂运算后相乘。

例如,(2*3)^4 = 2^4 * 3^4 = 16 * 81 = 1296。

大数模幂乘算法的快速实现

大数模幂乘算法的快速实现

大数模幂乘算法的快速实现
刘悦;李桂丽;田莹
【期刊名称】《信息技术》
【年(卷),期】2003(027)005
【摘要】大素数的选取是构造RSA密钥的关键,在素数的产生及测试是RSA公钥系统中的一个重要研究课题.描述了公钥密码体制中DSA、RSA等数据加密算法的原理及加密、解密过程,分析了各种算法的性能和适用的场合,针对上述算法的计算量巨大的问题,给出了实现数据加密较好的方法.理论和实验表明,该算法用于实现RSA算法,新算法的效率有明显的提高.
【总页数】3页(P25-27)
【作者】刘悦;李桂丽;田莹
【作者单位】鞍山科技大学计算机学院,鞍山,114044;鞍山科技大学计算机学院,鞍山,114044;鞍山科技大学计算机学院,鞍山,114044
【正文语种】中文
【中图分类】TP393.08
【相关文献】
1.基于离散对数体制的大数模幂乘算法的软件实现方法 [J], 芦殿军
2.基于窗口匹配算法的大数模幂运算快速实现研究 [J], 吕侃徽
3.大整数模幂的固定基窗口组合算法 [J], 瞿云云;包小敏;刘花;徐洋
4.基于RSA体制的大数模幂乘算法 [J], 芦殿军;张秉儒
5.一种大数模幂的快速实现方法 [J], 王英
因版权原因,仅展示原文概要,查看原文内容请购买。

快速幂算法c语言版超详细

快速幂算法c语言版超详细

快速幂算法c语言版(超详细) 快速幂算法是一种在数值运算中常见的高效算法,它通过将问题分解为多个相同的子问题来实现快速求解。

在实现快速幂算法时,需要注意避免溢出和减少不必要的计算。

下面是一个详细的 C 语言版快速幂算法实现。

#include <stdio.h>long long fast_power(long long base, long long exponent, long long mod) {long long result = 1;while (exponent > 0) {if (exponent & 1) { // exponent 是奇数result = (result * base) % mod;}base = (base * base) % mod;exponent >>= 1; // 等价于 exponent = exponent / 2;}return result;}int main() {long long base, exponent, mod;printf("请输入底数,指数和模数: ");scanf("%lld %lld %lld", &base, &exponent, &mod);long long result = fast_power(base, exponent, mod);printf("快速幂算法的结果为: %lld\n", result);return 0;}在这个实现中,我们使用了一个 while 循环来迭代计算幂次。

在每次循环中,我们检查 exponent 的最后一位是否为 1(用于判断 exponent 是否为奇数)。

如果是,我们将 result 乘以 base 并取模。

然后,我们将 base 平方并取模,以便在下一次循环中继续计算。

快速求幂算法

快速求幂算法

快速求幂算法快速求幂算法是一种在计算机科学和数学领域内常用的快速计算指数幂操作的算法。

该算法通过通过将指数拆分成二进制形式,并利用指数具有可重叠子问题结构的特点,从而快速计算出结果。

下面我将介绍快速求幂算法的背景、原理和实现方法。

背景指数运算是数学运算中的一种重要操作,因为许多数学问题和工程问题都要涉及到指数运算。

例如,加密算法中的RSA算法和离散对数问题,都需要涉及大数的指数运算。

但是,指数运算在大数的情况下计算量很大,需要进行优化和加速。

原理快速求幂算法的核心思想是基于指数的二进制表示,将指数拆分成二进制位,利用指数的可重叠子问题的结构缩短计算时间。

具体过程如下:1.将指数x转换为二进制表示形式;2.将x表示为$ x = w_0 2^0 + w_1 2^1 +...+ w_k 2^k$;3.计算$a^{2^k}$;4.然后依次计算$a^{2^{k-1}}$,$a^{2^{k-2}}$,...,$a^{2^0}$。

5.对于每个$2^n$,如果$w_n = 1$,就需要将其乘进结果中。

实现以下是该算法的python实现:def power(base, exponent):result = 1while exponent > 0:if exponent % 2 != 0:result = result * baseexponent = exponent // 2base = base * basereturn result下面是使用这个函数计算2^7的结果的示例代码:print(power(2, 7))结果是128。

优化在使用快速求幂算法时,有以下优化技巧可以使用:1.当幂指数为奇数时,先将结果乘进结果中,然后再通过减1的方式使指数变为偶数。

2.当使用大整数时,可以采用位运算的方式进行计算,从而提高计算速度。

3.对于特殊情况,比如需要模数的计算,也可以使用快速求幂的方法进行计算。

总结快速求幂算法是一种非常有用的算法,可以大大加速指数幂运算的计算,尤其是在大整数计算时有效。

大数快速模幂算法的硬件设计

大数快速模幂算法的硬件设计

收稿日期:2003209210基金项目:国家自然科学基金资助项目(60272091)作者简介:范明钰(1962-),女,教授,博士. 文章编号:025822724(2004)0320306205大数快速模幂算法的硬件设计范明钰1, 王建华2, 王光卫1(1.电子科技大学计算机学院,四川成都610054;2.北京航空航天大学计算机学院,北京100083)摘 要:将快速模幂算法、快速模乘算法和快速加法组合,提出了一种大数快速RSA 算法,并利用该算法给出了一个RSA 公开密钥的加解密硬件实现方案.首先采用m 2ary 方法,减少模乘运算次数;其次采用Montgomery 改进算法,减少模加运算次数;最后,采用高速加法器并调整加法与乘法的结构使其同时运行,以节约资源.对于1024位操作数,在100MHz 时钟频率下,加密速率约为390kbit/s.关键词:算法;模幂;模乘;RSA ;Montgomery 方法;选择清除累加器中图分类号:TN492,TP309 文献标识码:AH ardw are Design of F ast Module Exponential AlgorithmFA N M i ng 2yu 1, W A N G Jian 2hua 2, W A N G Guang 2wei1(1.School of Computer Science and Engineering ,University of Electronic Science and Technology of China ,Chengdu 610054,China ;2.School of Com puter Science and Engineering ,Beihang University ,Beijing 100083,China )Abstract :module exponential algorithm ,fast module multiplication algorithm and fast module addition algorithm were integrated to form a hybrid fast RSA algorithm for large number operations.A hardware scheme for implementation of RSA key was proposed using the proposed algorithm.In the algorithm ,m 2ary method is used in the first stage to reduce multiplication times ,then modified Montgomery method is used to decrease addition times ,and finally fast adders and multiplication unit are made to work synchronously by adjusting their structures.A processing speed of 390kbit/s at 100MHz clock was achieved for a 1024bit key operand.K ey w ords :algorithms ;module exponential ;module multiplication ;RSA ;Montgomery method ;SCA 模幂算法在许多应用领域如公开密钥体制中是一种重要的运算.给定n bit 字长的数M 和A ,模幂算法要求的是形如C =A e mod M 的结果,其中e <M.显然,不希望先计算A e ,再计算A e mod M.因为,在M 和e 为256bit 的情况下,为了存储A e ,至少需要log 2A e =e log 2A ≈2256×256=2264≈1080bit .由于在大多数应用中n ≥1024,因此要求算法的硬件实现一方面要快速,另一方面芯片占用面积要小.目前大多数RSA 实现都采用Montgomery 算法来减少模乘次数[1~9],建立了各种模幂运算和模乘运算方法.在研究中发现,这些方法一般都只讨论每种具体的改进,缺乏系统而完整的模幂运算方法的硬件实现,即通过算法设计减少模幂运算、模乘运算以及模加运算,最后得到完整的模幂硬件结构.因此试图对已有的方法加以改进,以获得一套较为完整的硬件解决方法.第39卷 第3期2004年6月 西 南 交 通 大 学 学 报J OU RNAL OF SOU THWEST J IAO TON G UN IV ERSIT YVol.39 No.3J un.20041 设计依据1.1 快速模幂算法 已有多种模幂算法,如二进制方法[1]、m 进制方法[1]、滑动窗技术[1,3]、变长非零窗技术[1]等.m 进制算法由Knuth [2]提出,假设m 可表示为2的幂,即m =2t ,则A e 就可以通过指数e 的二进制分组来计算.设e =(e k -1e k -2…e 1e 0)是指数e 的二进制表示,这样,可以把e 分成s 块,每块长度为t ,即k =st ,如果t 不能整除k ,则至多填充t -1个0.定义1 F i =(e is +s -1e is +s -2…e is )=∑t -1j =0e is +j 2j .算法1 Input :A ,e ,N ; Output :C =A e mod M.步骤1 预计算并存储A w mod M ,w =2,3,4,…,m -1;步骤2 将e 分解成t bit 长的字F i ,i =0,1,2,…,s -1;步骤3 C =A F s -1mod M ;步骤4 for i =s -1down to 0:(a )C =C 2tmod M ;(b )if F i ≠0,then C =C (A F i mod M );步骤5 return C.注意:0≤F i ≤m -1,e =∑s -1i =0F i 2it ,m 进制方法首先计算A w mod N ,w =2,3,4,…,m -1.则e 的每一位都按照t 位处理,从最高位到最低位.每一步中间结果都升2t 并乘以A F i mod N ,其中F i 是当前bit 组.这种方法将A e m od M 先进行w 次预计算,只有m -1项出现在计算中.假设e =250=(11111010)B ,s =4,t =2,则在预计算时,需要计算w =2,3(见表1).在步骤3中,C =AF s-1m od M =A F 3m od M =A 3m od M ,则计算A 250m od M 的过程见表2所示.计算A 250m od M 就只需要2+6+3=11次模乘和平方运算.表1 m 进制算法的预计算(步骤1)Tab.1 Pre 2calculation in m 2ary algorithm表2 m 进制算法的主体计算(步骤4)Tab.2 Main calculation in m 2ary algorithmbit wAw0001011A 102A2113A 3iF i步骤4(a )步骤4(b )211(A 3)4=A 12A 12A 3=A 15110(A 15)4=A 60A 60A 2=A 62010(A 62)4=A 248A248A 2=A250 一般,对于所有w =2,3,4,…,2t -1,幂运算大约只需要计算A w mod M.如果k 大,则相应计算数量也多.假设m =2t ,且k/t 是整数,则在算法1中的计算量为:乘法预计算(步骤1)的次数:m -2=2t -2;平方计算次数(步骤4(a )):(k/t -1)t =k -t ;乘积计算次数(步骤4(b )):(k/t -1)(1-1/m )=(k/t -1)(1-2-t ).m 进制算法平均需要2t -2+k -t +(k/t -1)(1-2-t )次乘法和平方运算.1.2 快速模乘算法 为了减少模乘积的运算次数,已经提出了多种算法,包括Karatsuba 2Ofman 算法、基于FF T 的乘法、Blakley 算法、Montgomery 算法等,其中Montgomery 算法是研究最多的一种[3,4,7~9],该算法尤其适用于模2幂的快速实现[4].假设2k -1≤M ≤2k ,r =2k ,且M 与r 互质,即gcd (M ,r )=1.算法2 假定:k 是A 和B 的位数,a i 为A 的第i 位s 0为S 的最低有效位(L SB ),S 和C 的定义参见第1.3节.Input :A ,B ,M ; Output :P =[A ×B ×(2k )-1]mod M.步骤1 S =0,C =0;步骤2 for i =0up to k -1:703第3期范明钰等:大数快速模幂算法的硬件设计(a )S ,C =S +C +a i B ;(b )S ,C =S +C +s 0M ;(c )S =S /2,C =C/2;步骤3 p =S +C ;步骤4 if p ≥M ,then p =p -M ;步骤5 return p.Montgomery 方法做了如下定义:定义2 A 的关于r 的M 剩余为: A =(A ×r )mod M ,对于给定的A 和B , A 和 B 关于r 的M 剩余R =( A × B ×r -1)mod M.因为 R =( A × B ×r -1)mod M =(A ×r ×B ×r ×r -1)mod M =(A ×B ×r -1)mod M ,显然, R 是R =(A ×B )mod M 关于r 的M 剩余.利用该方法原理,将A ×B 分解:A ×B =(a 0+a 12+…a k -12k -1)×B ;再乘以移位因子2-k :2k -1×A ×B =(2-k a 0+2-k -1a 1+ (2)-1a k -1)×B ,这样可以使存储器的长度维持在k 位.为了计算C =(A ×B )mod M ,Montgomery 算法需要使用2次:第1次:计算p =[A ×B ×(2k )-1]mod M ,即 R ;第2次:计算[p ×22k ×(2k )-1]mod M ,这样:[p ×22k ×(2k )-1]mod M ={[A ×B ×(2k )-1]×22k ×(2k )-1}mod M =(A ×B )mod M. 为了加快速度,便于硬件实现,将Montgomery 方法改进为算法2.引入S 和C 后,可以使用全加器,便于硬件实现.改进算法(算法2)的运算量为:步骤2(a ):k 次3bit 大数加法和k 2次2bit “与”运算(计算S ),3k 次“与”运算和k 次3bit 数加法(计算C ),步骤2(b )与步骤2(a )的运算量相同;步骤2(c ):2k 次右移移位;步骤3:1次大数加法;步骤4:至多1次减法.上述步骤2中,大数加法总运算次数为2k 次.由于统计意义上a i 和s 0中0,1个数大致相同,所以a i和s 0加法总运算次数为k 次.相对于加法来说由于“与”运算和移位运算可以在一个时钟周期内完成,故其耗时可以忽略,而3bit 数的加法相对于k 来说其耗时也可以忽略.故此改进的Montgomery 算法总共耗时为(k +2)次k bit 的大数加法.1.3 快速加法 4bit 的标准乘法计算方式是a 3a 2a 1a 0×b 3b 2b 1b 0t 03t 02t 01t 00t 13t 12t 11t 10t 23t 22t 21t 20+t 33t 32t 31t 30t 7t 6t 5t 4t 3t 2t 1t 0 如果采用硬件实现,则需要4次乘法,(4×2-2)次带进位加法.一般,两个k bit 数相加,至多需要计算(2k -2)次带进位bit 加.显然,带进位加是主要耗时耗存储空间的因素.目前已有多种实现快速大数加法的方法,如C arry Propagate Adder ,C arry C om pletion Adder ,C arry Look 2ahead Adder ,C arry S ave Adder ,C arry Delay Adder 等等[1,3].经研究和比较,选用改进的C arry S ave Adder (CS A )方法.其主要原理是,利用A ,B ,C 3个k bit 整数,产生2个整数C ′和S ,使得C ′+S =A +B +C.算法3 假定:A =∑k -1i =0a i 2i ,B =∑k -1i =0b i 2i ,C =∑k -1i =0c i 2i ,S =∑k -1i =0s i 2i . Input :A ,B ,C , Output :S ,C ′.步骤1 for i =0up to k -1:(a )s i =a i b i c i ;803西 南 交 通 大 学 学 报第39卷(b )c ′i +1=a i b i +a i c i +b i c i ;步骤2 return S ,C ′.算法3的运算量分析:XOR 运算(步骤1(a )):k 次,每次1个时钟周期;“与”运算和3个二进制数加运算(步骤1(b )):k 次,每次2个时钟周期.如果步骤1(a )和步骤1(b )采用并行实现,需要k 个时钟周期(参见图1和图2).2 硬件实现 采用自底向上方式构建快速模幂硬件.2.1 加法器 全加器(FA )的基本结构如图1所示.采用由这种全加器结合Carry Skip 和Carry Select 技术建立的高速加法器,完成一次1024bit 的加法运算只需要46.5ns [5].实际上,只要将模乘算法和模加算法作调整,使得模乘和模加运算能够在每个时钟周期内同时进行,就可以不浪费资源.由CSA 组成的k 位全加器硬件如图2所示.图1 单个全加器的基本结构Fig.1 Basic architecture of single full adder图2 由CSA 组成的全加器结构Fig.2 Basic architecture of k bits adder composed of CSA图3 改进的Montgomery 方法的模乘硬件基本结构Fig.3 Basic architecture of modulemultiplication with modified Montgomery method2.2 快速模乘器 利用算法3,P =Mon (A ,B ,M )=[A ×B ×(2k )-1]modM 模块硬件实现方法为:图3中令:A =P ,B =22k ,再运行一次,即可得C =(A ×B )mod M :C =Mon (P ,22k,M )=(A ×B )mod M.限于篇幅,硬件实现图略.2.3 快速模幂器 参见算法1:步骤1:预计算并存储A w mod M ,w =2,3,…,m -1,采用2.2节的P =Mon (A ,B ,M )mod M 模块,其中B =A ,硬件实现图略;步骤3:计算C =A F s -1mod M ,对于选定的m ,采用2.2节的模块;步骤4:对于i =s -1down to 0,循环计算:(a )计算C =C 2tmod M ,对于选定的t ,采用2.2节的模块;(b )如果F i ≠0,计算C =C 2tA F i mod M ,对于选定的t ,采用2.2节的模块.至此,一个完整的C =A e mod M 硬件实现就已经解决.利用文中所提出的模加、模乘和模幂3种快速算法组合,对于k =1024bit 的模幂运算,取最佳值t =903第3期范明钰等:大数快速模幂算法的硬件设计013西 南 交 通 大 学 学 报第39卷4,其运算量为[2t-2+k-t+(k/t-1)(1-2-t)]×2×(k+2)≈(1246)×2×1026=1246×2052=2556792(个时钟周期) 假设硬件工作在100MHz时钟下,则本设计的运算速度为100×106×1024/2556792≈390kbit/s.3 结 论 从3个方面对现有的大数模幂算法进行综合实现:首先采用m进制方法,减少模乘运算次数;其次采用Montgomery改进算法,减少模加运算次数;最后,采用高速加法器并调整加法与乘法的结构使其同时运行,以节约资源.对于1024位操作数,在100MHz时钟频率下,加密速率约为390kbit/s.参考文献:[1] K oc C K.High2speed RSA implementation[R].RSA Laboratories Technical Re port,TR801,V. 1.0,1996.[2] Knuth D E.The art of com puter programming:seminumerical algorithms(volume2)[M].Reading,MA:Addison2Wesley,1981.1234.[3] K oc C K.Analysis of sliding window techniques for exponentiation[J].Computers and Mathematics with A pplications,1995,30(10):17224.[4] Eldridge S E,Walter C D.Hardware im plementation of Montgomeryπs modular multiplication algorithm[J].IEEETransactions on Computers,1993,42(6):6932699.[5] Satoh A,Ooba N,Takano K,et al.High speed MARS hardware[EB/OL]./encryption/aes/round2/conf3/html,2003203.[6] 王许书,李占才,曲英杰.RSA密码系统有效实现算法[J].小型微型计算机系统,2002,5(3):5772579.[7] 方颖立,高志强.一种Montgomery模乘的硬件算法及其实现[J].微电子学,2002,4(8):2762282.[8] 王喜成,张振华.预计算式Montgomery算法研究[J].桂林电子工业学院学报,2001,3(9):37239.[9] 杨宁,董威,戎蒙恬.基于RSA系统的Montgomery算法的改进设计[J].通信技术,2003,2(134):87288.(上接第284页)本文中介绍了具有模糊费用系数的单车场单车型车辆调度问题,更复杂的模糊车辆调度问题,可能具有模糊需求量、模糊预约时间、多个车场、多种车型以及时间窗约束等特征,进一步的研究应从这些方面入手,找出求解具有这些特征的模糊VSP的启发式或亚启发式算法.参考文献:[1] Bodin L,G olden B,Assad A,et al.Routing and scheduling of vehicles and crews:the state of the art[J].Com puter andOperation Research,1983,10:622212.[2]郭耀煌,李军.车辆优化调度[M].成都:成都科技大学出版社,1994.22248.[3]G illet B,Miller L.A heuristic algorithm for the vehicle dis patch problem[J].Operational Research,1974,22:3402349.[4]Lin puter solutions of the traveling salesman problem[J].Bell System Technology Journal,1965,44:224522269.[5]姜大力,杨西龙,杜文.车辆路径问题的遗传算法研究[J].系统工程理论与实践,1999,6:40245.[6]Teodorovic D,Pavkovic G.A simulated annealing technique approach to the vehicle routing problem in the case of stochasticdemand[J].Trans portation Planning and Technology,1992,16:2612270.[7]袁庆达,杜文,周再玲.带软时间窗的混合车队车辆路线问题的模型和算法研究[J].西南交通大学学报,2001,36(4):4012406.[8]K aufmann A,Gu pta M M.Fuzzy mathematical models in engineering and management science[M].New Y ork:ElsevierScience Publishers B.V.,1988.37244.[9] Teodorovic D.Fuzzy set theory applications in traffic and trans portation[J].Europe Journal of Operation Research,1994,74:3792390.[10] Teodorovic D,Pavkovic G.The fuzzy set theory approach to the vehicle routing problem when demand at nodes isuncertain[11] 刘宝碇,赵瑞清.随机规划与模糊规划[M].北京:清华大学出版社,1998.15257.。

【原】模幂运算(ModularExponentiation)算法

【原】模幂运算(ModularExponentiation)算法

【原】模幂运算(ModularExponentiation)算法模幂运算常常作为⼀些算法的中间求解步骤,算法的思路⼗分巧妙并且⾼效。

模幂运算的描述如下:已知b, e, m, 求c。

形如:其中,b<m (若b>m,可转换b为b%=m)算法⼀:最显⽽易见的办法就是先求幂,再取模。

例如,得到 c = 445。

注意到b=4为1位,e=13为2位,m=497为3位,c=445为3位,但是为8位。

这很可能造成溢出,或者因为⼤整数运算⽽缓慢。

可以采⽤快速求幂法求得,时间复杂度为 O(loge)1:int Power(int b, int e)2: {3:if (0 == b || 1 == b || 0 == e)4:return 1;5:if (1 == e)6:return b;7:int n = e>>1;8:int tmp = Power(b, n);9:if (0 == (e&1))10:return tmp*tmp;11:else12:return tmp*tmp*b;13: }算法⼆:称为Right to left binary method这⾥利⽤了等式:同时将e表⽰作⼆进制表⽰形式:所以可以表⽰为:因此所需求得的结果c为:算法实现如下:1:typedef __int64 BigInt;2:3://modular exponentiation4: BigInt modexp(BigInt b,BigInt e,BigInt m)5: {6: b%=m;7: BigInt result=1;8:while(e>0)9: {10:if( e&1 == 1 )11: result = (result*b)%m;12:// multiply in this bit's contribution while using modulus to keep result small13:// move to the next bit of the exponent, square (and mod) the base accordingly14: e >>= 1;15: b = (b*b)%m;16: }17:return result;18: }算法时间复杂度为O(loge),若算上⼤整数相乘则总复杂度为O(loge*logm*logm)。

大数模幂运算的快速算法

大数模幂运算的快速算法

6. 输出 g;
算法 3 的实施过程中,令 M 为 2 的方幂,即 M=2k。经分析可看出,步骤 3 需要[logMx]*log2M= [log2x]次运算,步骤 4 中平均需要[logMx]*p
(ei!=0)=[ log2x ]*p(ei!=0)次模乘,这里 p(ei!=0)
k
=(1- 1 )为 ei 不为 0 的概率。如果将预计算中 M
2 常用的算法
2.1 二进制算法
模幂运算最常用也是最基本的算法,就是二
进制算法[5]。它先将指数用二进制表示,再采用
算法 1 描述的过程进行运算。
算法 1:
input:
a,
m,
x=∑
n −1 i=0
xi
为其二进制表示
output: g = ax(mod m)
pro: 1. 令 g = aX n−1 , I = n-2;
算法 5: input: a, m, x 的加法链为(u0, u1…us),长度 为 s,相关序列对为 w1…ws, wi = (i1, i2), output: g = ax(mod m) pro: 1.令 g0 = g; 2. i 从 1 递增到 s, 作如下操作: gi = gi1 * gi2; 3.输出 gs;
时所用的乘法次数最少,与一般的二进制算法相
比,运算次数减少了 15%。
附表 不同 k 值运算次数与占用资源的比较
k值
乘法次数 内存(按字节)
1
766
0
2
704
1028
3
666
3084
4
644
7196
5பைடு நூலகம்
640
15420
6
656

次方计算最快的方法

次方计算最快的方法

次方计算最快的方法次方计算是数学中常见的运算,在计算机科学中也是非常常用的操作。

然而,对于大的次方数的计算,直接使用循环进行计算会非常缓慢,因此我们需要寻找更快速的方法来计算次方。

1.快速幂算法快速幂算法是一种基于分治思想的算法,其时间复杂度为O(logn)。

具体实现方法为将指数n进行二进制拆分,然后通过不断平方和乘法的方式进行运算。

例如,计算a^11时,可以将11拆分为1011(二进制),则a^11 = a^(2^3) * a^(2^1) * a^(2^0) = a^8 * a^2 * a^1。

这样就可以通过3次乘法和3次平方运算得到a^11,大大提高了计算效率。

2.矩阵快速幂算法矩阵快速幂算法是一种基于快速幂算法的扩展,它利用矩阵乘法的性质来加速次方的计算。

具体实现方法为将底数a转化为一个矩阵,然后通过矩阵乘法的方式进行运算。

例如,计算a^11时,可以将a转化为一个2*2的矩阵,然后通过矩阵乘法运算得到a^11对应的矩阵。

这样就可以通过几次矩阵乘法得到结果,大大提高了计算效率。

3.位运算位运算是一种基于二进制的运算,它可以用来进行次方的计算。

具体实现方法为将指数n进行二进制拆分,然后通过位运算来进行运算。

例如,计算a^11时,可以将11拆分为1011(二进制),则a^11 = a^(2^3) * a^(2^1) * a^(2^0) = a^(1<<3) * a^(1<<1) * a^(1<<0)。

这样就可以通过几次位运算得到结果,大大提高了计算效率。

总之,以上三种方法都可以用来加速次方的计算,它们各有优缺点,可以根据具体的应用场景来选择使用哪种方法。

同时,还可以通过使用多线程等技术来进一步提高计算效率。

快速幂取余算法

快速幂取余算法

快速幂取余算法
快速幂取余算法是用来高效地计算大整数的指数幂取余操作的算法。

该算法基于指数的二进制表示形式,它充分利用了模运算的性质,从而可以将指数的幂运算转换成多次平方求模的运算。

具体步骤如下:
1.将指数e转化成二进制形式,如13的二进制为1101。

2.初始化r=1和x=a。

3.从二进制形式的最高位开始,依次计算出每一位的取值,如果该位为1,那么就将结果乘上x,并对p取模,如果该位为0,那么就将x平方并对p取模。

4.重复步骤 3,直到计算出所有位的取值,最终得到 r 的值即为
a^e mod p。

例如,计算 a^13 mod p 的结果可以按照以下步骤进行操作:
13的二进制表示为1101,因此需要计算出a^8 mod p,a^4 mod p,a^1 mod p三个数的乘积。

1.计算a^2 mod p = a*a mod p。

2.计算a^4 mod p = (a^2)^2 mod p。

3.计算a^8 mod p = (a^4)^2 mod p。

4.最后计算a^13 mod p = (a^8)*(a^4)*(a^1) mod p。

通过这种方法,能够在log n的时间复杂度内计算出任意一个数的指数幂取余。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

有朋友问我的博文《素性测试》中的Miller-Rabin算法的大数模幂运算快速算法怎么理解,由于在《素性测试》中没有讲解算法原理,所以在此单独一个篇文章详细讲这个算法。

这是一个在密码学中比较重要的算法,在我的《素性测试》一文则是用于实现费马小定理。

首先我们先把问题简化一下,看看如何快速求a^b.
先看看我们熟知的两个数学公式:
a^(2c) = (a^c)^2;
a^(2c+1) = a*((a^c)^2);
我们就利用这两个数学公式来解决这个问题,比如a=3,b=13时,我们把b写成二进制的形式13(10)=1101(2),我们从低位到高位运算,每运算一位可以将b右移一位,上面的例子可以转化成3^13 = 3^1 * 3^4 * 3^8,结合上面的两个数学公式我们可以写出如下的代码:
代码清单:
[java]view plain copy
如上面的叙述叙述中可以看出快速pow算法的时间复杂度取决于b的二进制位数,而传统的一位一位累乘的pow算法的时间复杂度取决于b的大小,例如上述例子中,两种算法的运算次数分别为4次,和13次。

随着b的增大,效率上的差距是显然的。

下面进入我们的主题---大数模幂运算快速算法(a^b % m)
要计算这个,我们首先还要知道一个数学公式:
a^b % m = (...((a % m) * a) % m) ......* a) % m其中a%m有b个
下面我还用上面b=13的例子,利用这个公式来证明下
a^13 % m = ((a^8) % m) * ((a^4) % m) * ((a^1) % m)
证明:
由a^b % m = (...((a % m) * a) % m) ......* a) % m其中a%m有b个得
a^8 % m = (...((a % m) * a) % m) ......* a) % m其中a%m有8个
a^4 % m = (...((a % m) * a) % m) ......* a) % m其中a%m有4个
a^1 % m = (...((a % m) * a) % m) ......* a) % m 其中a%m有1个
所以((a^8) % m) * ((a^4) % m) * ((a^1) % m) = (...((a % m) * a) % m) ......* a) % m 其中a%m有13个= a^13 % m ;
证毕。

由上面我们证明的公式和第一个pow的例子,容易写出代码如下:
代码清单:
[java]view plain copy
解释:当b=1101(2)时,从第1位开始result累乘,a = (a*a)%m加上循环可以看成表达式(a%m)^2 % m....因为(a%m)^2 % m = a^2 % m ,所以我们可以把a^13%m 看成((a^1) % m) ,((a^4) % m) ,((a^8) % m)的累乘,最后对m取模。

但累乘很容易造成溢出,所以我们可以把代码改成如下形式:
代码清单:
[java]view plain copy。

相关文档
最新文档