或许以前已经有不少人实现过了,我只是无聊随便写写练练手………………
实现思路是依据以前无聊时老妈教的手动开方的方法,具体可以去网上查一下,现在的课上都不教这个,多好玩的东西啊= =
import java.math.BigDecimal;import java.math.BigInteger;public class BigSquareRoot {final static BigInteger HUNDRED = BigInteger.valueOf(100);public static BigDecimal sqrt(BigDecimal number, int scale, int roundingMode) {if (number.compareTo(BigDecimal.ZERO) <0)throw new ArithmeticException("sqrt with negative");BigInteger integer = number.toBigInteger();StringBuffer sb = new StringBuffer();String strInt = integer.toString();int lenInt = strInt.length();if (lenInt % 2 != 0) {strInt = '0' + strInt;lenInt++;}BigInteger res = BigInteger.ZERO;BigInteger rem = BigInteger.ZERO;for (int i = 0; i 0) {j = j.subtract(BigInteger.ONE);if (((res.add(j)).multiply(j)).compareTo(rem) <= 0) {break;}}res = res.add(j);rem = rem.subtract(res.multiply(j));res = res.add(j);sb.append(j);}sb.append('.');BigDecimal fraction = number.subtract(number.setScale(0, BigDecimal.ROUND_DOWN));int fracLen = (fraction.scale() + 1) / 2;fraction = fraction.movePointRight(fracLen * 2);String strFrac = fraction.toPlainString();for (int i = 0; i <= scale; i++) {res = res.multiply(BigInteger.TEN);rem = rem.multiply(HUNDRED);if (i 0) {j = j.subtract(BigInteger.ONE);if (((res.add(j)).multiply(j)).compareTo(rem) <= 0) {break;}}res = res.add(j);rem = rem.subtract(res.multiply(j));res = res.add(j);sb.append(j);}return new BigDecimal(sb.toString()).setScale(scale, roundingMode);}public static BigDecimal sqrt(BigDecimal number, int scale) {return sqrt(number, scale, BigDecimal.ROUND_HALF_UP);}public static BigDecimal sqrt(BigDecimal number) {int scale = number.scale() * 2;if (scale <50)scale = 50;return sqrt(number, scale, BigDecimal.ROUND_HALF_UP);}public static void main(String args[]) {BigDecimal num = new BigDecimal("6510354513.6564897413514568413");long time = System.nanoTime();BigDecimal root = sqrt(num, 1000);time = System.nanoTime() - time;System.out.println(root);System.out.println(root.pow(2));System.out.println(time);}}
执行结果为:
80686.76789695129274934163167415572667227399843721516347158767523580494926630778178430590951466379111804908857587446512732813032883173748853326070513301760285725581720542170290426420802841219508916055188622734932391913201321482936884453475292438465177510253838847107428192523540143783448954382809081595849921120413548084334663215893873187391659928133773996691705498117040762580786535487490032515047912273090549137010629298585004337459716319984878355766005793739292339332464428038041322980167371596723174825202497634647135810481429155090019959431924156948154893647401523124167363012332695879106288856148931252358224933171849176260762233258194024032205319263928083338545236947805395632931332327299009882430134640204409763960847967390025813800940751692874927103010714873124915302903422135690536804619019074812892301526435999701388617884895991186748498151644251941384019184992330095716507616259437813674551010197203487418421717729159422780119055940318303673431936060471243739689515243596006764061625063628813676510354513.6564897413514568412999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999926101857018822195229120108939890605223148311244415513788935359677052676317603215287681687248342873265150453633526747537236014827438259428569752954222443778544944033142404025142609964950919522314365182865958736415320894713698528528362886891537824020109421322773475625149587856634040959968482365944490429209988298566890680862317720866525191937026893789345730612180276656627062704168052625236841102345948799655110460391390302950170083523059788586776118307153717195882656868508634921003283484107506051230944462214561655110811989362386457901381371094116726117997257123357470563886214035746556929599452326174296080759360172792926272885615388050356145973630091010329970787377071326701815417116554517843000234245994056167888453015116676996418045399873420955405169122232655370071294850845464960894274665168357263422432309827443557629070976914823912072234212690264557460977055821182997270551415300643484661401600695692159450660675883266224059348596262991032020567847404732223257704456747933698583093453429051578868946726188
效率不算太差,在我的机器上精度为50的需要约5ms,100大约8-9ms,1000约45-47ms,1000约1.5s……
精度还是很有保障的~~
下面说明一下使用方法:
public static BigDecimal sqrt(BigDecimal number, int scale, int roundingMode)参数:number为需要开方的数scale为精度,精确到小数点后第几位roundingMode为舍入方式,就是BigDecimal类的那几个返回值:开方结果
public static BigDecimal sqrt(BigDecimal number, int scale)参数:number为需要开方的数scale为精度,精确到小数点后第几位返回值:开方结果舍入方式为四舍五入
public static BigDecimal sqrt(BigDecimal number)参数:number为需要开方的数返回值:开方结果舍入方式为四舍五入精度为原数字精度的两倍,如果不足50则补足到50