java 整数加减乘除_java实现超大整数加减乘除四则运算

packagecom.hdwang;importjava.util.regex.Matcher;importjava.util.regex.Pattern;/*** 大数四则运算(超出long型的大数(64位:18446744073709551615))

* Created by hdwang on 2017/10/9.*/

public classCalculator {/*** 两数相加

*@paramnumStr1 数1

*@paramnumStr2 数2

*@return结果*/

public staticString add(String numStr1, String numStr2){int numLen1 =numStr1.length();int numLen2 =numStr2.length();int[] numArray1 = new int[numLen1]; //数字数组

int[] numArray2 = new int[numLen2];//"12345"-> [5,4,3,2,1]

for(int i=0;i

String c= numStr1.substring(i,i+1);

numArray1[numLen1-i-1] = Integer.parseInt(c); //低位存字符串尾部数字

}for(int i=0;i

String c= numStr2.substring(i,i+1);

numArray2[numLen2-i-1] = Integer.parseInt(c); //低位存字符串尾部数字

}int minLen = 0; //取长度小的数位数

int maxLen = 0; //取长度大的数位数

int[] maxArray = null; //长度大的数

if(numLen1

minLen=numLen1;

maxLen=numLen2;

maxArray=numArray2;

}else{

minLen=numLen2;

maxLen=numLen1;

maxArray=numArray1;

}int[] resultArray = new int[maxLen+1]; //考虑到可能会进位,多给一个元素空间//两数长度相同的部分,同位相加,超出9进1

int added = 0;int i=0;for(;i

if(t>9){

added= 1; //进1

resultArray[i] = t-10; //当前位计算结果

}else{

added= 0; //不进位

resultArray[i] = t; //当前位计算结果

}

}//长度超出部分累加

for(;i

if(t>9){

added= 1; //进1

resultArray[i] = t-10; //当前位计算结果

}else{

added= 0; //不进位

resultArray[i] = t; //当前位计算结果

}

}

resultArray[i]= added; //最高位//拼接结果 [1,4,8,2,0] -> 2841

StringBuilder builder = newStringBuilder();for(int n=resultArray.length-1;n>=0;n--){//如果最高位为0,移除

if(n==resultArray.length-1 && resultArray[resultArray.length-1]==0){continue; //跳过

}else{

builder.append(resultArray[n]);

}

}returnbuilder.toString();

}/*** 两数相减

*@paramnumStr1 数1

*@paramnumStr2 数2

*@return结果*/

public staticString subtract(String numStr1,String numStr2){int numLen1 =numStr1.length();int numLen2 =numStr2.length();int[] numArray1 = new int[numLen1]; //数字数组

int[] numArray2 = new int[numLen2];//"12345"-> [5,4,3,2,1]

for(int i=0;i

String c= numStr1.substring(i,i+1);

numArray1[numLen1-i-1] = Integer.parseInt(c); //低位存字符串尾部数字

}for(int i=0;i

String c= numStr2.substring(i,i+1);

numArray2[numLen2-i-1] = Integer.parseInt(c); //低位存字符串尾部数字

}int minLen = 0; //取长度小的数位数

int maxLen = 0; //取长度大的数位数

int[] maxArray = null; //数值大的数

if(numLen1

minLen=numLen1;

maxLen=numLen2;

maxArray=numArray2;

}else{

minLen=numLen2;

maxLen=numLen1;

maxArray=numArray1;if(numLen1 == numLen2){ //等于

maxArray =getMaxNumber(numArray1,numArray2);

}

}int[] minArray = maxArray==numArray1?numArray2:numArray1; //数值小的数

int[] resultArray = new int[maxLen];//大数-小数,同位相减,小于0借位

int subtracted = 0;int i=0;for(;i

if(t<0){

subtracted= 1; //向高位借1,暂存起来

resultArray[i] = t+10; //当前位计算结果(借1相当于借了10)

}else{

subtracted= 0; //不借位

resultArray[i] = t; //当前位计算结果

}

}//大数超出部分减掉借位

for(;i

if(t<0){

subtracted= 1; //进1

resultArray[i] = t+10; //当前位计算结果

}else{

subtracted= 0; //不借位

resultArray[i] = t; //当前位计算结果

}

}//拼接结果 [1,4,8,2,0] -> 2841

StringBuilder builder = newStringBuilder();boolean highBitNotEqualZero = false; //存在高位不为0的情况,低位0保留

for(int n=resultArray.length-1;n>=0;n--){//如果高位为0,移除

if(resultArray[n]==0 && !highBitNotEqualZero && n!=0){ //高位无用的0去除

continue; //跳过

}else{

highBitNotEqualZero= true; //找到不为0的位

builder.append(resultArray[n]);

}

}if(maxArray == numArray1){ //第一个数大或相等

}else{ //第一个数小于第二个数,相减为负数

builder.insert(0,"-");

}returnbuilder.toString();

}/*** 两数相乘

*@paramnumStr1 数1

*@paramnumStr2 数2

*@return结果*/

public staticString multiply(String numStr1,String numStr2){int numLen1 =numStr1.length();int numLen2 =numStr2.length();int[] numArray1 = new int[numLen1]; //数字数组

int[] numArray2 = new int[numLen2];//"12345"-> [5,4,3,2,1]

for(int i=0;i

String c= numStr1.substring(i,i+1);

numArray1[numLen1-i-1] = Integer.parseInt(c); //低位存字符串尾部数字

}for(int i=0;i

String c= numStr2.substring(i,i+1);

numArray2[numLen2-i-1] = Integer.parseInt(c); //低位存字符串尾部数字

}int minLen = 0; //取长度小的数位数

int maxLen = 0; //取长度大的数位数

int[] maxArray = null; //长度大的数

int[] minArray = null; //长度小的数

if(numLen1

minLen=numLen1;

maxLen=numLen2;

minArray=numArray1;

maxArray=numArray2;

}else{

minLen=numLen2;

maxLen=numLen1;

minArray=numArray2;

maxArray=numArray1;

}//二维数组存储结果,例如:23*23 ->[[6,9],[4,6]] ,内部括号(低维)存某位的相乘结果,高维低位存个位,十位...

int[][] resultArray = new int[minLen][maxLen+1];//长度大的数*长度小的数的每一位,分别存到相应数组中,然后累加

for(int h=0;h

int l=0;int added = 0;for(;l

int t = maxArray[l]*minArray[h]+added; //长度大的数的每一位*长度小的数的个位、十位...

if(t>9){

added= t/10; //进位

resultArray[h][l] = t%10; //当前位计算结果

}else{

added= 0; //不进位

resultArray[h][l] = t; //当前位计算结果

}

}

resultArray[h][l]= added; //个位、十位...的计算结果的最高位

}//对结果补位(左移),个位不动,十位补0,百位补00...,然后累加

int[] sum = null; //最终累加结果

int[] lowBitResult = null; //低位补0结果(前一位)

for(int h=0;h

if(h==0){ //个位

r =bitResult;

sum=r;

lowBitResult= r; //记录下来,待下次循环累加

}else{ //十位...的计算结果

r = new int[resultArray[h].length+h]; //初始化默认就是0的

int rLen = r.length-1;for(int i=bitResult.length-1;i>=0;i--){ //从高位开始复制到新数组

r[rLen--] =bitResult[i];

}//累加之前的数

sum = new int[r.length+1]; //取高位长度+1,可能进位//================加法核心算法====================//两数长度相同的部分,同位相加,超出9进1

int added = 0;int i=0;for(;i

if(t>9){

added= 1; //进1

sum[i] = t-10; //当前位计算结果

}else{

added= 0; //不进位

sum[i] = t; //当前位计算结果

}

}//长度超出部分累加

for(;i

if(t>9){

added= 1; //进1

sum[i] = t-10; //当前位计算结果

}else{

added= 0; //不进位

sum[i] = t; //当前位计算结果

}

}

sum[i]= added; //最高位//===============================================

lowBitResult= sum; //记录下来,待下次循环累加

}

}//拼接结果 [1,4,8,2,0] -> 2841

StringBuilder builder = newStringBuilder();boolean existHighNotZero = false; //高位存在不为0的,这个0就不能移除

for(int n=sum.length-1;n>=0;n--){//移除高位无效的0,保留最后一个0

if(sum[n]==0 && !existHighNotZero && n!=0){continue; //跳过

}else{

existHighNotZero= true;

builder.append(sum[n]);

}

}returnbuilder.toString();

}/*** 两数相除

*@paramnumStr1 数1(被除数)

*@paramnumStr2 数2(除数,不能超过long型)

*@return结果*/

public staticString divide(String numStr1,String numStr2){int numLen1 =numStr1.length();int numLen2 =numStr2.length();int[] numArray1 = new int[numLen1]; //数字数组

int[] numArray2 = new int[numLen2];//"12345"-> [5,4,3,2,1]

for(int i=0;i

String c= numStr1.substring(i,i+1);

numArray1[numLen1-i-1] = Integer.parseInt(c); //低位存字符串尾部数字

}for(int i=0;i

String c= numStr2.substring(i,i+1);

numArray2[numLen2-i-1] = Integer.parseInt(c); //低位存字符串尾部数字

}int effectiveNum = (numLen1 >= numLen2 ? numLen1:numLen2)+16; //有效位数: 默认大数长度+16

int[] resultArray = new int[effectiveNum]; //高位存高位//将被除数的每一位除以除数,取整为该位结果,取余暂存借给低位(除数不能大过long型,除非除法转换为减法)

long yu = 0;int resultIndex = effectiveNum-1;for(int i=numArray1.length-1;i>=0;i--){long num = yu * 10 + numArray1[i]; //被除数该位为:余数*10+自己

int r= (int)(num / Long.parseLong(numStr2)); //取整

yu = num % Long.parseLong(numStr2); //取余

resultArray[resultIndex--] =r;

}int decimalPoint = effectiveNum-numArray1.length-1; //小数点位置

if(yu!=0){int decimal = decimalPoint; //小数

for(int i=0;i

int r= (int)(num / Long.parseLong(numStr2)); //取整

yu = num % Long.parseLong(numStr2); //取余

resultArray[decimal--] =r;if(yu==0){break; //余数为0,提前退出

}

}

}//拼接结果

StringBuilder builder = newStringBuilder();boolean existHighNotZero = false;for(int i=effectiveNum-1;i>=0;i--){if(i==decimalPoint){

builder.append(".");

}if(resultArray[i]==0){if(!existHighNotZero && i>decimalPoint+1){ //跳过高位无用的0

continue;

}

}else{

existHighNotZero= true;

}

builder.append(resultArray[i]);

}

String result=builder.toString();//去除尾部无用的0

int endIndex =result.length();for(int i=result.length()-1;i>=0;i--){char c =result.charAt(i);if(c!='0'){

endIndex= i+1;break;

}

}//去除多余的小数点

if(result.charAt(endIndex-1)=='.'){

endIndex= endIndex-1;

}

result= result.substring(0,endIndex);returnresult;

}/*** 两数相除(增强版)

*@paramnumStr1 数1(被除数)

*@paramnumStr2 数2(除数)

*@return结果*/

public staticString divideEnhanced(String numStr1,String numStr2){int numLen1 =numStr1.length();int numLen2 =numStr2.length();int[] numArray1 = new int[numLen1]; //数字数组

int[] numArray2 = new int[numLen2];//"12345"-> [5,4,3,2,1]

for(int i=0;i

String c= numStr1.substring(i,i+1);

numArray1[numLen1-i-1] = Integer.parseInt(c); //低位存字符串尾部数字

}for(int i=0;i

String c= numStr2.substring(i,i+1);

numArray2[numLen2-i-1] = Integer.parseInt(c); //低位存字符串尾部数字

}int effectiveNum = (numLen1 >= numLen2 ? numLen1:numLen2)+16; //有效位数: 默认大数长度+16

int[] resultArray = new int[effectiveNum]; //高位存高位//将被除数的每一位除以除数,取整为该位结果,取余暂存借给低位(除数不能大过long型,除非除法转换为减法)

String yu = "0";int resultIndex = effectiveNum-1;for(int i=numArray1.length-1;i>=0;i--){

String num= "0".equals(yu)?numArray1[i]+"":add(yu+"0",numArray1[i]+""); //被除数该位为:余数*10+自己

DivideResult result =getDivideResult(num,numStr2);

String r= result.getR() ; //取整

yu = result.getYu(); //取余

resultArray[resultIndex--] = Integer.parseInt(r); //某位上的结果肯定小于10

}int decimalPoint = effectiveNum-numArray1.length-1; //小数点位置

if(!"0".equals(yu)){int decimal = decimalPoint; //小数

for(int i=0;i

String num= yu+"0"; //小数部分被除数补0

DivideResult result =getDivideResult(num,numStr2);

String r= result.getR() ; //取整

yu = result.getYu(); //取余

resultArray[decimal--] =Integer.parseInt(r);if("0".equals(yu)){break; //余数为0,提前退出

}

}

}//拼接结果

StringBuilder builder = newStringBuilder();boolean existHighNotZero = false;for(int i=effectiveNum-1;i>=0;i--){if(i==decimalPoint){

builder.append(".");

}if(resultArray[i]==0){if(!existHighNotZero && i>decimalPoint+1){ //跳过高位无用的0

continue;

}

}else{

existHighNotZero= true;

}

builder.append(resultArray[i]);

}

String result=builder.toString();//去除尾部无用的0

int endIndex =result.length();for(int i=result.length()-1;i>=0;i--){char c =result.charAt(i);if(c!='0'){

endIndex= i+1;break;

}

}//去除多余的小数点

if(result.charAt(endIndex-1)=='.'){

endIndex= endIndex-1;

}

result= result.substring(0,endIndex);returnresult;

}/*** 校验数字是否合法

*@paramnumStr 数字字符串

*@return是否合法*/

public static booleannumberValid(String numStr){

Pattern pattern= Pattern.compile("^[1-9]\\d*$|0");

Matcher matcher=pattern.matcher(numStr);returnmatcher.matches();

}/*** 计算大数

*@paramnumArray1 数1

*@paramnumArray2 数2

*@return大数*/

public static int[] getMaxNumber(int[] numArray1, int[] numArray2) {for(int i=numArray1.length-1;i>=0;i--){if(numArray1[i]>numArray2[i]){returnnumArray1;

}else{if(numArray1[i]==numArray2[i]){continue; //待继续比较

}else{returnnumArray2;

}

}

}return numArray1; //全部相等,返回第一个

}/*** 除法转换为减法

*@paramnumStr1 数1(被除数)

*@paramnumStr2 数2(除数)

*@return除的结果*/

public staticDivideResult getDivideResult(String numStr1,String numStr2){

DivideResult result= newDivideResult();

String r= "";//String times = "0";

int times = 0; //取整不会大于9的(被除数(余数+某位)/除数(肯定大于余数)这个过程是,被除数逐渐增大到可以除以除数为止,此时被除数>=除数,刚刚好,所以被除数最多比除数多1位,两数相差肯定小于10倍)

while (true){

r=subtract(numStr1,numStr2);//times = add(times,"1");//次数递增

times++;if("0".equals(r)){ //除尽了

result.setYu("0");

result.setR(times+"");break;

}else if(r.startsWith("-")){ //负数,多减了一次

result.setYu(numStr1); //上次减下来多余的数值,就是余数//result.setR(subtract(times,"1"));

result.setR((times-1)+"");break;

}

numStr1= r; //被减数重置为剩余的数值

}returnresult;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值