整数运算中的问题和解决方法

资源类型:pdf 资源大小:320.00KB 文档分类:工业技术 上传者:吕建晓

文档信息

【作者】 周尚超 

【关键词】同余式 模运算 算法 

【出版日期】2005-04-30

【摘要】给出整数运算中存在的问题和解决办法.

【刊名】华东交通大学学报

全文阅读

1 引 言在各种计算机语言中,整数是在一定范围内运行的.如果超出范围,就会出错.本文在C语言中讨论此问题并提出解决的办法.例1.计算组合数C[m][n],它表示从m个元素中取n个元素的种数.如果将它定义为unsignedint型整数,它表示的最大整数为m=4294967295.C[80000][2]=80000 79999/2=3199960000/.计算机的计算结果是错的,这是因为它先计算80000 79999,此值已超过它表示的最大整数m=4294967295.如将运算改为(80000/2) 79999,则计算结果正确.在数论,组合数学和密码学和计算机科学中经常要用到整数取模运算.各种计算机语言都设置了整数取模运算.C语言中的取模运算符为%.这些问题可归纳为:如果参与运算的数和运算结果都小于和等于某最大值m的整数.如何使运算结果正确.例1 的运算可归结为计算A=a b/s,其中a,b,s的值和运算结果A都是不超过某最大值m的正数.计算方法如下:d=gcd(a,s);//gcd表示最大公因数a=a/d;s=s/d;b=b/s;A=a b;在取模运算中,所有参与运算的数和运算结果都小于某数m.要解决此问题只要有正确的加法运算和乘法运算就行了.下面给出加法运算的函数add和乘法运算的函数mult(m为模).参与运算的数为0,1,...,m-1.令M=m-1.计算(a+b)%m(a,b<m)的算法(函数)如下:如果a+b的值大于M,则运算(a+b)%m的值为a+b-m.由于不能使用大于或等于m的值,直接写s=(a+b)%m就会出错,写为a-(M-b+1)则正确(b>0).intadd(inta,intb,intM){int s;if(a==0||b==0)s=a+b;elseif(a>=M-b+1)s=a-(M-b+1);elses=a+b;returns;}对于乘法运算(m为模),不能使用大于或等于m的数.先以a=51,b=23,m=100.计算计算a b%m方法如下Apr.,200551 23=(3+12 4) 23=3 23+12 92=69+12 (-8)=69-96=69+4=73.根据此例的方法,我们给出计算a b%m,a,b<m的函数mult,在此函数中出现的数都是小于m的数.intmult(inta,intb,intM){ints,r,d,t,k;//M=m-1if(a==1)returnb;if(a==0||b==0)return0;if(b==1)returna;if(a==M)returnM-b+1;if(b==M)returnM-a+1;if(a<=M/b)returna b;k=0;if(b>M-b){k=1;b=M-b+1;}//使d=M/b>1,s<a/2d=M/b;t=M%b;//M=d b+td b=M-ts=a/d;r=a%d;//a=s d+ra b=(s d+r) b=r b+(M-t) sif(k==0)add(r b,mult(s,M-t,M),M);//d b<=M,r<d,r b<MelsereturnreturnM-add(r b,mult(s,M-t),M)+1;}mult是一个递归函数,每次调用后s的值减少1/2以上,计算速度是很快的.运算中不能使用数m,但有时会遇到运算m/a.例2.如果已知a,要求模m的逆元b,即使a b=1(modm).由数论,a存在逆元的充分必要条件是gcd(a,m)=1.这里gcd表示最大公因数.计算逆元b的算法如下.r=1;b1=0;b2=1;While(r!=0){q=m/a;r=m%a;if(r!=0){m=a;a=r;t=b2;b2=b1-b2 q;b1=t;continue;}break;}if(a==1)b=b2;elseb=0;//逆元不存在在例2中,用到q=m/a;r=m%a;在不使用m的情况下,要计算q=m/a和r=m%a,程序如下//m/a=(M+1)/a;m%a=(M+1)%aq=M/a;if(M%a==a-1)q++;r=M%a;r++;if(r==a)r=0;因此例2中,计算逆元b的算法如下.M0=M;//M=m-1;r=1;b1=0;b2=1;flag=0;while(r!=0){if(flag==0){q=M/a;//第1次计算时flag=0,M为最大值m-1,计算的是m/a,m%aif(M%a==a-1)q++;r=M%a;r++;if(r==a)r=0;flag=1;}else{q=M/a;r=M%a;}//M已不是最大值m-1if(r!=0){M=a;a=r;t=b2;d=mult(b2,q,M0);if(b1>=d)b2=b1-d;elseb2=M0-d+b1+1;b1=t;flag=1;continue;}break;}if(a==1)s=b2;elses=0;//逆元不存以下给出几个计算实例例3.在密码学中,要计算a^n%m.当n值很大时,使用下列快速算法.b=1;while(n>1){if(n%==0){n/=2;a=a a%m;}else{n--;b=b a%m;}}b=b a%m;b的值即为a^n%m;使用add和mult函数,则程序如下:b=1;while(n>1){if(n%==0){n/=2;a=mult(a,a,M);}else{n--;b=mult(b,a,M);}}b=mult(b,a,M);例4.北京大学在线问题(http://acm.pku.edu.cn/JudgeOnline)第2115题.一个超级时钟有m个刻度,称为1点,2点,...,m点.m点又称为零点.从零点出发,每次走a点,问能否走到b点,如能,要走多少次.例如对m=12,从零点出发,每次走3点,走1次到3点,走2次到6点,还可走到9点和12点,但不能走到其他点.如每次走5点则可走到12个点中的所有点.因此这题归结于计算方程ax=b(modm),m<=2^32的解这题中的m可能为最大值m=2^32,unsignedint型整数表示的最大值为M=2^32-1.利用例2中的方法先计算a的逆元s,则其解为x=s b(modm)整数运算中的问题和解决方法@周尚超$华东交通大学基础科学学院!江西南昌330013同余式;;模运算;;算法给出整数运算中存在的问题和解决办法.江西省自然科学基金项目;; 华东交通大学科技基金项目.

1

问答

我要提问