您的位置:首页 > 编程语言 > Java开发

Java模拟两个大整数的加法、乘法、除法

2017-03-14 17:52 435 查看
package ddd;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class BigIntegerAddition {

/**
*
* 问题:java实现两个大数相加,可能存在溢出。 如123456789 + 987654321 返回 1111111110
*
* 解决办法:
* 1.直接用BigInteger
*
* 2.模拟手算加法,进位相加(暂时没有考虑负数的情况),该类模拟两个大数的相加, 相乘,相除。至于相减,看了该类的相加就知道如何实现了。
* 该类中的加、乘、除的算法思路与人工的计算方式一致。虽然算法目的是达到了,但效率的话的确有待商榷,因为本人能力有限,实在是想不到更好的实现方式,还望
* 各位路过的高人指点!!!若有更好的实现方式,记得留言咯!
*/
public static void main(String[] args) {

String x = "23456789";
String y = "987654321";

BigInteger a = new BigInteger(x);
BigInteger b = new BigInteger(y);
BigInteger c = a.add(b);
System.out.println(c.toString());

System.out.println(add(x, y));

System.out.println(add("-100", "1"));
System.out.println(add("-1000", "1"));
System.out.println(add("-1", "1"));
System.out.println(add("-17", "901"));

System.out.println(add("1", "-100"));
System.out.println(add("1", "-1000"));
System.out.println(add("1", "-1"));
System.out.println(add("901", "-17"));

System.out.println(posMultiPos("556", "7"));

System.out.println(posMultiPos("195", "5"));

System.out.println(posMultiPos("919", "8"));

System.out.println("--->" + trimPrefixedZero("0"));

System.out.println(posMultiPos("99", "0"));

System.out.println(divid("138", "12", 6));
System.out.println(divid("10", "3", 6));

}

/**
* 两个整数的加法运算,考虑正负数,由于减法可以转化为加法运算,
* 所以本人并没有直接给出求大整数减法的算法
* @param x
* @param y
* @return
*/
public static String add(String x, String y) {
if (isNullOrEmpty(x) || isNullOrEmpty(y)) {
return null;
}
if (!isNumeric(x) || !isNumeric(y)) {
return null;
}
if (x.equals("0")) {
return y;
}
if (y.equals("0")) {
return x;
}

if (x.charAt(0) == '-' && y.charAt(0) == '-') {

x = x.substring(1);
y = y.substring(1);
return "-" + posAddPos(x, y);

} else if (x.charAt(0) != '-' && y.charAt(0) != '-') {

return posAddPos(x, y);

} else if (x.charAt(0) == '-' && y.charAt(0) != '-') {

return negAddPos(x, y);

} else if (x.charAt(0) != '-' && y.charAt(0) == '-') {

String tem = x;
x = y;
y = tem;
return negAddPos(x, y);
}

return null;
}

/**
* 一个负数与一个正数的加法
* @param x
* @param y
* @return
*/
public static String negAddPos(String x, String y) {

if (x.charAt(0) != '-' || y.charAt(0) == '-') {
throw new IllegalArgumentException("x必须是负数数,y必须是正数");
}
// 判断x代表的负数的绝对值是否比正数y的绝对值大
boolean isAbsXLarger = false;

x = x.substring(1);

if (x.length() > y.length()) {
isAbsXLarger = true;
String tmp = x;
x = y;
y = tmp;
} else if (x.length() == y.length()) {
isAbsXLarger = isAbsXLarger(x, y);
if (isAbsXLarger) {
String tmp = x;
x = y;
y = tmp;
}
}

x = addZeroToFirst(x, y.length());

int len = y.length();
int[] a = toIntArray(y);
int[] b = toIntArray(x);
int[] c = new int[len + 1];

for (int i = 0; i < len; i++) {
int ac = a[len - 1 - i];
int bc = b[len - 1 - i];

if (ac - bc >= 0) {
c[len - i] = ac - bc;
} else {

c[len - i] = (ac + 10) - bc;

int r = 1;
while ((len - 1 - i - r) >= 0 && a[len - 1 - i - r] == 0) {
a[len - 1 - i - r] = 9;
r++;
}
a[len - 1 - i - r] = a[len - 1 - i - r] - 1;
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= len; i++) {
sb.append(c[i]);
}

String z = trimPrefixedZero(sb.toString());

if (z.equals("0")) {
z = "";
}

if (z.length() > 0 && isAbsXLarger) {
return "-" + sb.toString();
} else if (z.length() > 0) {
return sb.toString();
} else {
return "0";
}
}

/**
* 两个正数的加法
* @param x
* @param y
* @return
*/
public static String posAddPos(String x, String y) {
if (x.length() > y.length()) {
String tmp = x;
x = y;
y = tmp;
}
x = addZeroToFirst(x, y.length());

String z = "";
int len = x.length();
int[] a = toIntArray(x);
int[] b = toIntArray(y);
int[] c = new int[len + 1];
int d = 0;
for (int i = 0; i < len; i++) {
int tmpSum = a[len - 1 - i] + b[len - 1 - i] + d;
c[len - i] = tmpSum % 10;
d = tmpSum / 10;
}
c[0] = d;

StringBuilder sb = new StringBuilder();
for (int i = 0; i <= len; i++) {
sb.append(c[i]);
}

z = trimPrefixedZero(sb.toString());

return z;
}

/**
* 大整数的乘法
* @param x
* @param y
* @return
*/
public static String multi(String x, String y) {
if (isNullOrEmpty(x) || isNullOrEmpty(y)) {
return null;
}
if (!isNumeric(x) || !isNumeric(y)) {
return null;
}

if (x.charAt(0) == '-' && y.charAt(0) == '-') {

x = x.substring(1);
y = y.substring(1);
return posMultiPos(x, y);

} else if (x.charAt(0) != '-' && y.charAt(0) != '-') {

return posMultiPos(x, y);

} else if (x.charAt(0) == '-' && y.charAt(0) != '-') {

x = x.substring(1);
return "-" + posMultiPos(x, y);

} else if (x.charAt(0) != '-' && y.charAt(0) == '-') {

y = y.substring(1);
return "-" + posMultiPos(x, y);
}

return null;
}

/**
* 一个多位数与一个个位数的乘法,注:这两个数都只能是正数
* @param x
* @param y
* @return
*/
private static String posMultiSingleDigit(String x, String y) {
if (y.length() != 1 || x.charAt(0) == '-') {
throw new IllegalArgumentException("参数异常");
}
String z = "";
int len = x.length();
int[] a = toIntArray(x);
int b = Integer.parseInt(y);
int[] c = new int[len + 1];

int d = 0;
for (int i = 0; i < len; i++) {
int tempV = a[len - 1 - i] * b;
int r = (tempV % 10) + d;
d = tempV / 10;
if (r >= 10) {
c[len - i] = r - 10;
d = d + 1;
} else {
c[len - i] = r;
}
}
c[0] = d;

StringBuilder sb = new StringBuilder();
for (int i = 0; i <= len; i++) {
sb.append(c[i]);
}

z = trimPrefixedZero(sb.toString());

return z;
}

/**
* 两个正数的乘法
* @param x
* @param y
* @return
*/
public static String posMultiPos(String x, String y) {
if (x.length() < y.length()) {
String tem = x;
x = y;
y = tem;
}

int[] b = toIntArray(y);
int len = b.length;

String[] temp = new String[len];

for (int i = 0; i < len; i++) {

temp[len - 1 - i] = posMultiSingleDigit(x, b[len - 1 - i] + "");
temp[len - 1 - i] += getZeroStringOfLenght(i);
}

String result = "0";
for (int i = 0; i < len; i++) {
result = posAddPos(result, temp[i]);
}

return result;

}

/**
* 大整数的除法, 如果不能整除, 则小数保留位数为precision,如果能整除,则保留一位小数
* @param x
* @param y
* @param precision 小数的精度
* @return
*/
public static String divid(String x, String y, int precision) {
if (isNullOrEmpty(x) || isNullOrEmpty(y)) {
return null;
}
if (!isNumeric(x) || !isNumeric(y)) {
return null;
}
boolean flag = false;

List<String> li = new ArrayList<String>();
if (x.charAt(0) == '-' && y.charAt(0) == '-') {

x = x.substring(1);
y = y.substring(1);
posDividPos(x, y, "", li, precision, false);

} else if (x.charAt(0) != '-' && y.charAt(0) != '-') {

posDividPos(x, y, "", li, precision, false);

} else if (x.charAt(0) == '-' && y.charAt(0) != '-') {
flag = true;
x = x.substring(1);
posDividPos(x, y, "", li, precision, false);

} else if (x.charAt(0) != '-' && y.charAt(0) == '-') {
flag = true;
y = y.substring(1);
posDividPos(x, y, "", li, precision, false);
}

String result = "";
for(String ele : li)
{
result += ele;
}

result = trimPrefixedZero(result);

if(flag && !result.equals("0")) {
result = "-" + result;
}

return result;
}

/**
* 两个正整数的除法
* @param x
* @param y
* @param temp
* @param li
*/
private static void posDividPos(String x, String y, String temp, List<String> li, int precision, boolean dotIncluded) {

if (x.length() == 0 && precision  == 0) {
return;
}

char[] charArray = x.toCharArray();
String[] xArray = new String[charArray.length];
for (int i = 0; i < charArray.length; i++) {
String s = String.valueOf(charArray[i]);
xArray[i] = s;
}

List<String> xList = new ArrayList<String>(Arrays.asList(xArray));
if (xList.size() > 0) {
temp += xList.remove(0);
} else {
if(!dotIncluded) {
li.add(".");
dotIncluded = true;
}

if(precision > 0) {
precision--;
temp += "0";
}
}
temp = trimPrefixedZero(temp);

while (isAbsXLarger(y, temp)) {
li.add("0");
if (xList.size() > 0) {
temp = temp + xList.remove(0);
} else if(precision > 0) {
if(!dotIncluded) {
li.add(".");
dotIncluded = true;
}
temp = temp + "0";
precision--;
temp = trimPrefixedZero(temp);
if(temp.equals("0")) {
//                  return;
}
} else {
return;
}
}

int k = cacu(temp, y);
li.add(k + "");
String result = add(temp, "-" + posMultiSingleDigit(y, k + ""));
result = trimPrefixedZero(result);

if (result.equals("0")) {
result = "";
}
temp = result;

String newX = "";
for (String str : xList) {
newX += str;
}
System.out.println(result);
posDividPos(newX, y, result, li, precision, dotIncluded);
}

public static String getZeroStringOfLenght(int a) {
String str = "";
for (int i = 0; i < a; i++) {
str += "0";
}
return str;
}

public static int[] toIntArray(String str) {
int len = str.length();
int[] result = new int[len];
for (int i = 0; i < len; i++) {
result[i] = str.charAt(i) - '0';
}
return result;
}

public static String addZeroToFirst(String str, int length) {
StringBuilder sb = new StringBuilder();
int diff = length - str.length();
while (diff > 0) {
sb.append("0");
diff--;
}
sb.append(str);
return sb.toString();
}

public static boolean isNumeric(String str) {
Pattern p = Pattern.compile("^\\-?[0-9]*$");
Matcher isNum = p.matcher(str);
return isNum.matches();
}

public static boolean isNullOrEmpty(String str) {
if (str == null) {
return true;
}
if (("").equals(str.trim())) {
return true;
}
return false;
}

public static boolean isAbsXLarger(String x, String y) {
if (x.length() > y.length()) {
return true;
} else if (x.length() == y.length()) {

int[] xArray = toIntArray(x);
int[] yArray = toIntArray(y);
for (int i = 0; i < xArray.length; i++) {
if (xArray[i] > yArray[i]) {
return true;
} else if (xArray[i] == yArray[i]) {
continue;
} else {
return false;
}
}
}

return false;
}

public static String trimPrefixedZero(String z) {
while (z.length() > 1 && z.charAt(0) == '0') {
z = z.substring(1);
}
return z;
}

/**
* 该方法相当于求 x/y的值,注意x、y都是一个正整数
* @param x
* @param y
* @return
*/
public static int cacu(String x, String y) {

int k = 0;
for (int i = 0; i <= 9; i++) {
if (isAbsXLarger(x, posMultiSingleDigit(y, i + "")) || (x.equals(posMultiSingleDigit(y, i + "")))) {
//              System.out.println(x);
//              System.out.println(posMultiSingleDigit(y, i + ""));
k = i;
}
}

return k;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐