原来还有如此简单粗暴的办法,<传送门>
当数字比较小(比如10^9)时,我们可以用sqrt函数直接求平方根。但是当数字达到10^20时,sqrt就没用了。此时我们可以用二分来找平方根。但是如果又要精确到小数点后若干位,那么二分也不知道要跑多久。于是我们使用手动开方的算法。
首先将数字每两位分成一段。如:745836942。就分成:
7|45|83|69|42,即从个位开始分。共分成五段,第一段是7。
对第一段的数字7开方取整,可得到2。此时,要在2后面接一个数字b,并在7后面加上下一段的数45,使产生的两位数2b的平方不大于745。
我们知道,数是10a+b,其平方是100a^2+20ab+b^2。我们可以暂时忽略b^2,而产生一个“试商”b。即b = (745 - 100a^2) / 20a = (745 - 100*2*2) / (20 * 2) = 8.625 ≈ 8(向下取整)。但是,我们发现28的平方=784>745,于是这个试商需要减少为7。然而,当a=0时,上述求试商的方法不在适用,但我们可以直接取下一段的两位数开方。如√45≈6。求出试商后,用745-^2得到新的“第一段”的数。
过程即:取出第一段的数mn,开方得到a,然后接上第二段的数pq,用mnpq0a^2得到“余数”x,x/20a得到试商b,然后调整b(当20*a*b+b*b>x时b需要减少),调整后,将x-20a*b-b*b作为新的余数x',新的a就是。由于前面已经将100a^2减掉,所以后面每次都不用再减去100a^2。重复步骤,直到开方完毕,或达到要求的精度为止。最后得到的a就是平方根。
如求745836942的平方根:
7|45|83|69|42
①a=√7≈2,b=(745-400)/40≈8,28^2=784>745 ==> b=7 ==> 27^2=729<745,745r9 = 16
②a=27,b=1683/540≈3,27*20*3+3*3=1629<1683,168329 = 54
③a=273,b=5469/5460≈1,273*20*1+1*1=5461<5469 ==> b=1, 5469T61=8
④a=2731,b=842/54620≈0,2731*20*0+0*0<842 ==> b=0,84296 = 842
至此,745836942的整数部分已经求出来,就是27310。如果还要求小数部分,在后面接0即可。注意,在被开方数字很大(10^100)时,需要用高精度计算a。