大整数相乘(包含小数)

大整数相乘,输入小数也可以,其原理是分块相乘,将输入的数对半分成高位和低位,使大整数划分为小数,然后将小数相乘获取原高地位的大数

可以通过规律:大整数1*大整数2=高位1*高位2+中位进位+中位(高位1乘低位2+低位1乘高位2)+低位进位+低位1*低位2

拼接大整数


java代码如下:


// 分块相乘

public String bigMul(String num1, String num2, int len) {


if (null == num1 || "".equals(num1) || null == num2 || "" == num2) {

return "0";

}

int pointNum = 0;// 小数点移位距离

// 如果是小数

if (num1.contains(".")) {

pointNum += num1.length()-num1.indexOf(".")-1;

String h = num1.substring(0, num1.indexOf("."));

String l = num1.substring(num1.indexOf(".") + 1);

num1 = h + l;

}

if (num2.contains(".")) {

pointNum += num2.length()-num2.indexOf(".")-1;

String h = num2.substring(0, num2.indexOf("."));

String l = num2.substring(num2.indexOf(".") + 1);

num2 = h + l;

}


// 取得最长的数


// 将长度调整相同

num1 = formatNumber(num1, len);

num2 = formatNumber(num2, len);


// 如果长度小于4,则直接乘

if (num1.length() <= 4) {

String result = String.valueOf(Integer.valueOf(num1)

* Integer.valueOf(num2));

String setPoint = setPoint(pointNum, result);

return setPoint;

}

// 如果长度大于四,将两个数分成高低位

int halfLen = len / 2;

int halfLen2 = len - halfLen;

String num1H = num1.substring(0, halfLen);

String num1L = num1.substring(halfLen);

String num2H = num2.substring(0, halfLen);

String num2L = num2.substring(halfLen);


int maxLen = Math.max(halfLen, halfLen2);

// 高位*高位

String H1H2 = bigMul(num1H, num2H, halfLen);

// 高位*低位

String H1L2 = bigMul(num1H, num2L, maxLen);

// 低位乘高位

String L1H2 = bigMul(num1L, num2H, maxLen);

// 低位*低位

String L1L2 = bigMul(num1L, num2L, halfLen2);


// 从低位开始,先取低位的进位

String[] carryL = getCarry(L1L2, halfLen2);


// 将中间两位相加

String mid = additionMid(H1L2, L1H2);


String carry = carryL[0];

if (carry != null && !carry.equals("0")) {

mid = additionMid(mid, carry);

}

// 首位加上中位进位再取进位

String[] carryMid = getCarry(mid, maxLen);

String carryM = carryMid[0];

String high = "";

high = additionMid(H1H2, carryM);

// 将三者叠加即可

String result = high + carryMid[1] + carryL[1];


result = setPoint(pointNum, result);

return result;

}


private String setPoint(int pointNum, String result) {

// 设置小数点

if (pointNum > 0) {

String sRes = "." + result.substring(result.length() - pointNum);

String hRes = result.substring(0, result.length() - pointNum);

result = hRes + sRes;

}

return result;

}


private String additionMid(String h1l2, String l1h2) {

int carryFlag = 0;

int maxLength = Math.max(h1l2.length(), l1h2.length());

h1l2 = formatNumber(h1l2, maxLength);

l1h2 = formatNumber(l1h2, maxLength);

String numRes = "";

String[] result = { "0", numRes };

for (int i = maxLength - 1; i >= 0; i--) {

int num1 = Integer.parseInt(h1l2.substring(i, i + 1));

int num2 = Integer.parseInt(l1h2.substring(i, i + 1));

int singleAddition = num1 + num2 + carryFlag;

carryFlag = 0;

if (singleAddition >= 10) {

carryFlag = 1;

singleAddition -= 10;

}

numRes = singleAddition + numRes;

}

result[0] = String.valueOf(carryFlag);

result[1] = numRes;

// 如果最高位有进位,则加上去

if (carryFlag != 0) {

numRes = carryFlag + numRes;

}


return numRes;

}


// 0:进位,1:值

private String[] getCarry(String l1l2, int len) {

String carry[] = { "0", l1l2 };

if (l1l2.length() > len) {

// 有进位

int sub = -len + l1l2.length();// 获得多出来的长度

String substring = l1l2.substring(0, sub);// 截取进位长度

String valueString = l1l2.substring(sub);// 截取进位后的长度

carry[0] = substring;

carry[1] = valueString;

} else {

for (int i = l1l2.length(); i < len; i++) {

carry[1] = "0" + carry[1];

}

}

return carry;

}


@Test

public void fun() {

//首数字不能为零

String num1 = "14.4";

String num2 = "1.42";

String bigMul = bigMul(num1, num2,

Math.max(num1.length(), num2.length()));


bigMul = getPruNum(bigMul);

System.out.println(bigMul);

}


private String getPruNum(String bigMul) {

for (int i = 0; i < bigMul.length(); i++) {

String w = bigMul.substring(0, 1);

if (w.equals("0")) {

bigMul = bigMul.substring(1);

} else {

return bigMul;

}

}

return bigMul;

}

你可能感兴趣的:(数据结构)