首先我们要明确的是这里的n指的是输入数据所使用的二进制位数。比如我们现在常用用的32位或64位。
我在来看计算机是怎样做除法的。给定两个自然数m1, m2。我们假设m1>m2;这样我们有了一个代数的表达式:m1=pm2+q。很显然p是商,q是余数且m2>q;我们也很容易理解为m1迭代连续p次减m2,最后得出结果如下式:
m1=m1(0),
m1(k)=m1(k-1) - m2, 0<=k<=p
当k=0时,什么运算都没发生。
当p>k>0时,m1(k)<m2;因此运算有了再次进行的理由。
当0<=m1(k)< m2时,运算停止,k相等于计数迭代减法的次数,也就有k=p,为商;m1(k)为余数。
假设这一切发生在一个模拟图灵机上时,就返回除法的商或者余数。
但是当前公开或使用的大整数除法即使采用Knuth的经典名著“The Art of Computer Programming”的第4.3.1节中的猜商值公式来计算,也需要多次试运算,所有这些大整数除法最大的缺点是时间复杂度:T(n) = O(nn)。
用85/6来举例,85/6=1010101/110
001 101(0101)左移1位到第3位都小于110,因此商=000 // *85移动3位
002 1010(101)左移四位是1010,比110大,商=0001,余数=1010-110=100(101) // *85移动1位
003 余数100(101)左移一位是1001,比110大,商=00011,余数=1001-110=11(01) //*余数移动1位
004 余数11(01)左移一位是110,等于110,商=000111,余数=0(1) //*余数移动1位
005 余数0(1)左移一位是01,小于110,商=0001110,余数=01//*余数移动1位
因此85/6=1010101/110=0001110,即14,余数为最后的余数1。计算机需要总共移位6次,不难想象当给定两个大数时,第一次除法就需移动n次。
最坏的情况下,余数为n-1位数,接着m2又要继续做除法,我们就得到一个表示移动次数的表达式:
N=(n+(n-1)+(n-2)+...+1)=n(n-1)/2,很显然辗转除法的时间复杂度为O(nn)。