Java实现大数相加,有小数的情况

输入用例:

1234567890123456789012345678901234567890.1234567890123456789012345678901234567890
1000000000100000000010000000001000000000.1000000000100000000010000000001000000000

输出:
2234567890223456789022345678902234567890.223456789022345678902234567890223456789 

先上代码了,有空再记录一下思想。。

package practice;

import java.util.Scanner;

public class Test2 {
	//str1和str2是2个要相加的大数,carrybit是进位,取值只能是0和1
	public static StringBuffer bigNumberPlus(String str1, String str2, int carrybit) {
       //两个都是小数的情况
        if(str1.contains(".")== true && str2.contains(".")== true){
        	//将大数分为2部分,整数部分和小数部分,使用split时"."一定要转义转义!!
        	String subStr1[] = str1.split("\\.");
        	String subStr2[] = str2.split("\\.");
        	//主要先处理小数部分,对于小数部分的处理办法就是搞成和整数一样
        	//Sec表示的是第二部分也就是小数部分
        	StringBuffer str1Sec = new StringBuffer(subStr1[1]);
        	StringBuffer str2Sec = new StringBuffer(subStr2[1]);
            int lenLong;//记录子串中比较长的那个数的长度
        	if (str1Sec.length()<str2Sec.length()){
        		lenLong = str2Sec.length();
                int num = str2Sec.length() - str1Sec.length();
                //对短的那个小数后面补0
                //这里与整数部分的处理不同,如果是整数要先反转再补0,而小数需要先补0再翻转
                //不理解得话自己算一下,分开计算
                while (num-- > 0)
                	str1Sec.append('0');
        	}
        	else{
        		lenLong = str1Sec.length();
                int num = str1Sec.length() - str2Sec.length();
                while (num-- > 0)
                	str2Sec.append('0');
        	}
            //到这里得到的是2个长度相等的小数部分 
        	//例如 str1=1.2 str2=2.499 则str1Sec="200" str2Sec="499"
        	StringBuffer result_Sec = bigNumberPlus(new String(str1Sec), new String(str2Sec),0);
        	//虽然现在得到了小数部分相加的结果result_Sec,但是可能存在进位
        	//如果存在进位,需要加到整数部分,这也是先处理小数部分的真正原因
        	//默认进位为0
        	int carryBit = 0;
        	//判断是否存在进位,若最后的结果大于小数最长的长度,则存在进位
        	//存在进位,则将carryBit的值置为1,并删掉记录进位的元素
        	if (result_Sec.length()>lenLong){
        		 carryBit = 1;
        		 result_Sec.deleteCharAt(0);
        	}
        	//整数部分的计算
        	StringBuffer result_Fir = bigNumberPlus(subStr1[0], subStr2[0],carryBit);
        	//整数部分+小数点+小数部分就是结果了
        	StringBuffer result = result_Fir.append("."+result_Sec);
        	return result;
        }
        //其中一个是小数的情况,比较简单,不说了
        if (str1.contains(".")== true && str2.contains(".") == false){
        	String subStr1[] = str1.split("\\.");
        	StringBuffer result_Fir = bigNumberPlus(subStr1[0],str2,0);
        	StringBuffer result_Sec = new StringBuffer(subStr1[1]);
        	StringBuffer result = result_Fir.append("."+result_Sec);
        	return result;
        }
        
        if (str2.contains(".")== true && str1.contains(".") == false){
        	String subStr2[] = str2.split("\\.");
        	StringBuffer result_Fir = bigNumberPlus(subStr2[0],str1,0);
        	StringBuffer result_Sec = new StringBuffer(subStr2[1]);
        	StringBuffer result = result_Fir.append("."+result_Sec);
        	return result;
        }
        	
        //反转这一步很巧妙,因为相加的时候从个位开始计算
        StringBuffer s1 = new StringBuffer(str1).reverse();
        StringBuffer s2 = new StringBuffer(str2).reverse();
        StringBuffer res = new StringBuffer();

        int len1 = s1.length();
        int len2 = s2.length();
        int len;
        
       
        
        if (len1 < len2) {
            len = len2;
            int count = len2 - len1;
            while (count-- > 0)
                s1.append('0');
        } else {
            len = len1;
            int count = len1 - len2;
            while (count-- > 0)
                s2.append('0');
        }

        int overflow = carrybit; 
        int num;

        for (int i = 0; i < len; i++) {
            num = s1.charAt(i) - '0' + s2.charAt(i) - '0' + overflow;
            if (num >= 10) {
                overflow = 1;
                num -= 10;
            } else {
                overflow = 0;
            }
            res.append(String.valueOf(num));
        }

        if (overflow == 1)
            res.append(1);

        return res.reverse();
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in=new Scanner(System.in);
		while(in.hasNext()){
			String firstnum=in.next();
			String secondnum=in.next() ;
			StringBuffer result = bigNumberPlus(firstnum, secondnum, 0);
			char res[] = result.toString().toCharArray();
			int pos = res.length;
			if (res[res.length-1]=='0')
				pos = res.length-1;
			//去掉无效的0和小数点,注意题目中给的条件
			for (int i = res.length-1; i>0 ;i--){
                //只有当前位置为0且前面位置为0或.时,将pos往前移
				if(res[i]=='0' && (res[i-1]=='0' || res[i-1]=='.')){
					pos = i-1;
				}
                //一旦不符合前移的条件就结束
				else{
					break;
				}
			}
			result = result.delete(pos,res.length);
			System.out.println(result);
		}
	}

}
发布了52 篇原创文章 · 获赞 6 · 访问量 9011

猜你喜欢

转载自blog.csdn.net/PMPWDF/article/details/98893418
今日推荐