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;
}
}
Java模拟两个大整数的加法、乘法、除法
原文作者:大整数乘法问题
原文地址: https://blog.csdn.net/nmgrd/article/details/62046774
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/nmgrd/article/details/62046774
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。