题目描述
在计算机中,由于处理器位宽限制,只能处理有限精度的十进制整数加减法,比如在32位宽处理器计算机中,参与运算的操作数和结果必须在-231~231-1之间。
如果需要进行更大范围的十进制整数加法,需要使用特殊的方式实现,比如使用字符串保存操作数和结果,采取逐位运算的方式。如下:
9876543210 + 1234567890 = ?
让字符串 num1=”9876543210”,字符串 num2=”1234567890”,结果保存在字符串 result = “11111111100”。
-9876543210 + (-1234567890) = ?
让字符串 num1=”-9876543210”,字符串 num2=”-1234567890”,结果保存在字符串 result = “-11111111100”。
要求编程实现上述高精度的十进制加法。
要求实现方法:
public String add (String num1, String num2)
【输入】num1:字符串形式操作数1,如果操作数为负,则num1的前缀为符号位’-’
num2:字符串形式操作数2,如果操作数为负,则num2的前缀为符号位’-’
【返回】保存加法计算结果字符串,如果结果为负,则字符串的前缀为’-‘注:
(1)当输入为正数时,’+’不会出现在输入字符串中;当输入为负数时,’-‘会出现在输入字符串中,且一定在输入字符串最左边位置;
(2)输入字符串所有位均代表有效数字,即不存在由’0’开始的输入字符串,比如”0012”, “-0012”不会出现;
(3)要求输出字符串所有位均为有效数字,结果为正或0时’+’不出现在输出字符串,结果为负时输出字符串最左边位置为’-‘。输入描述:
输入两个字符串
输出描述:
输出给求和后的结果
示例1
输入
9876543210
1234567890
输出
11111111100
实现代码:
- 思路:
①分为两种情况,同号和异号
②同号:分为同正和同负,区别在于对字符数组的截止的点一个是0,一个是1
③异号:具体分为以下四种情况(具体见代码)
④重在细节
package cn.c_shuang.demo54;
import java.util.Scanner;
/**
* 无线OSS-高精度整数加法
* @author Cshuang
*
*/
public class Main{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
while(in.hasNext()){
String num1=in.next();
String num2=in.next();
System.out.println(add(num1,num2));
}
in.close();
}
private static String add(String num1, String num2) {
char[]ch1=num1.toCharArray();
char[]ch2=num2.toCharArray();
boolean flag=true;
if((ch1[0]=='-'&&ch2[0]=='-')||(ch1[0]!='-'&&ch2[0]!='-')){
if(ch1[0]=='-'){
flag=false;
}
return twoSame(ch1,ch2,flag);
}else{
//flag默认为true,即结果为正
if((ch1[0]=='-'&&ch1.length-1>ch2.length)){
flag=false;
return twoDiff(ch1,ch2,flag);//负的多的在前面
}if((ch1[0]=='-'&&ch1.length-1<ch2.length)){
return twoDiff(ch2,ch1,flag);//正的多的在前面
}else if(ch2[0]=='-'&&ch2.length-1>ch1.length){
flag=false;
return twoDiff(ch2,ch1,flag);//负的多的在前面
}else //if(ch2[0]=='-'&&ch2.length-1<ch1.length){
return twoDiff(ch1,ch2,flag);//正的多的在前面
//}
}
}
private static String twoDiff(char[] ch1, char[] ch2, boolean flag) {
StringBuilder rs=new StringBuilder();
int endLen1=0,endLen2=0;
if(!flag)//如果相减为负
endLen1=1;
else
endLen2=1;
int b=0;//借位
int len1=ch1.length;
int len2=ch2.length;
int temp = 0;
//避免将减号加进计算
while(len1>endLen1&&len2>endLen2){
//记住这里一定要有括号,否则出现计算错误
temp = ch1[len1-1]-'0'-(ch2[len2-1]-'0')-b;
if(temp<0){
b=1;
temp+=10;
}else
b=0;
rs.append(temp);
len1--;
len2--;
}
//
while(len1>endLen1){
temp=ch1[len1-1]-'0'-b;
if(temp<0){
b=1;
temp+=10;
}else
b=0;
rs.append(temp);
len1--;
}
if(!flag)
rs.append("-");
return rs.reverse().toString();
}
private static String twoSame(char[]ch1,char[]ch2,boolean flag){
StringBuilder rs=new StringBuilder();
int endNum=0;
if(!flag){//如果两个同为负号
endNum=1;
}
int c=0;//进位
int len1=ch1.length;
int len2=ch2.length;
int temp = 0;
while(len1>endNum&&len2>endNum){
temp = ch1[len1-1]-'0'+ch2[len2-1]-'0'+c;
if(temp>=10){
c=temp/10;
temp%=10;
}else
c=0;
rs.append(temp);
len1--;
len2--;
}
int resLen=len1==endNum?len2:len1;//多于的部分
char[] resCh=len1==0?ch2:ch1;
while(resLen>endNum){
temp=resCh[resLen-1]-'0'+c;
if(temp>=10){
c=temp/10;
temp%=10;
}else
c=0;
rs.append(temp);
resLen--;
}
if(c!=0)
rs.append(c);
if(!flag)
rs.append("-");
return rs.reverse().toString();
}
}