package com.around.generator.rapid;
/**
* @Title: 自定义加减运算
* @Description: 测试两个比较大的数进行相加,相减的数学运算
* @Company:
* @Author: moodincode
* @Create: Date:2020年06月28日
*/
public class TestAdd {
//此字符为输入可选字符,他的长度就是最大的进制数,此处最大为62进制,如果让程序支持大于62进制,则需要加入其他字符来扩充
public static final String SCALE_STR="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static void main(String[] args) {
//可选数0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,
// 例如16进制,首位数最大为f,2进制,首位数最大为1,10进制首位数最大为9
//支持小数,负数
String a="-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
//支持小数,负数
String b="1";
//进制数,只支持2进制到62进制,如果需要更大的进制运算,可以加入特殊字符到scaleStr中
int scale=10;
String s = calculateAdd(a, b, scale);
System.out.println(a+"加"+b+"的结果为:"+s);
String s2 = calculateSubtraction(a, b, scale);
System.out.println(a+"减"+b+"的结果为:"+s2);
}
/**
* 计算A+B的结果
* @param a ,可为小数,或负数
* @param b
* @param scale 进制 支持2-62进制
* @return
*/
public static String calculateAdd(String a,String b,int scale ){
//两个负数相加
if(a.startsWith("-")&& b.startsWith("-")){
// -1 + -1 ==> - (1+1)
return "-"+calculateAdd(a.replace("-",""),
b.replace("-",""),scale);
}else if(a.startsWith("-")){
//转减法 -1+1 ==>1-1
return calculateSubtraction(b,a.replace("-",""),scale);
}else if(b.startsWith("-")){
//转减法,1+-1 ==>1-1
return calculateSubtraction(a,b.replace("-",""),scale);
}
String supportChar=SCALE_STR.substring(0,scale);
//检查字符是否输入合理
checkFormat(a, b, scale, SCALE_STR.length(), supportChar);
//计算小数点后的位数
//小数的位数
int s=0;
int b1 = a.indexOf(".");
int b2 = b.indexOf(".");
b1=b1==-1?0:a.length()-b1-1;
b2=b2==-1?0:b.length()-b2-1;
//System.out.println("b1="+b1+",b2="+b2);
//调整小数位
if(b1>0 ||b2>0){
s=b1>b2?b1:b2;
if(b1==0){
a+=".";
}
while (b1<s){
a+="0";
b1++;
}
if(b2==0){
b+=".";
}
while (b2<s){
b+="0";
b2++;
}
}
//System.out.println("a="+a+",b="+b);
//运算过程中去除小数点
a=a.replace(".","");
b=b.replace(".","");
char[] aC=a.toCharArray();
char[] bC=b.toCharArray();
int aL=aC.length;
int bL=bC.length;
int maxL=aL>bL?aL:bL;
int[] aI=new int[maxL+1];
int[] bI=new int[maxL+1];
//结果列
int[] sI=new int[maxL+1];
//将a填入数组
for (int i = 0; i <aL ; i++) {
aI[maxL-i]=supportChar.indexOf(aC[aL-i-1]);
}
//将b填入数组
for (int i = 0; i <bL ; i++) {
bI[maxL-i]=supportChar.indexOf(bC[bL-i-1]);
}
//从个位数起,进行相同位数相加
for (int i = 0; i <maxL+1 ; i++) {
int sum=aI[maxL-i]+bI[maxL-i];
sI[maxL-i]=sum%scale;
if(i<maxL){
//将进位的结果放在aI上
aI[maxL-i-1]+=sum/scale;
}
}
//调整返回结果
return adjustResult(supportChar, s, sI);
}
/**
* 计算A-B的结果
* @param a ,a
* @param b
* @param scale 进制 支持2-62进制
* @return
*/
public static String calculateSubtraction(String a,String b,int scale ){
if(a.startsWith("-")&& b.startsWith("-")){
//-1 - -2 ==>2-1
return calculateSubtraction(b.replace("-",""),
a.replace("-",""),scale);
}else if(a.startsWith("-")){
//转加法
// -1 - 1 ==> -(1+1)
return "-"+calculateAdd(a.replace("-",""),b,scale);
}else if(b.startsWith("-")){
//转加法 1 - -1 ==> 1+1
return calculateAdd(a,b.replace("-",""),scale);
}
String supportChar=SCALE_STR.substring(0,scale);
//检查字符是否输入合理
checkFormat(a, b, scale, SCALE_STR.length(), supportChar);
//计算小数点后的位数
//小数的位数
int s=0;
int b1 = a.indexOf(".");
int b2 = b.indexOf(".");
b1=b1==-1?0:a.length()-b1-1;
b2=b2==-1?0:b.length()-b2-1;
// System.out.println("b1="+b1+",b2="+b2);
//调整小数位
if(b1>0 ||b2>0){
s=b1>b2?b1:b2;
if(b1==0){
a+=".";
}
while (b1<s){
a+="0";
b1++;
}
if(b2==0){
b+=".";
}
while (b2<s){
b+="0";
b2++;
}
}
//System.out.println("a="+a+",b="+b);
//运算过程中去除小数点
a=a.replace(".","");
b=b.replace(".","");
char[] aC=a.toCharArray();
char[] bC=b.toCharArray();
int aL=aC.length;
int bL=bC.length;
int maxL=aL>bL?aL:bL;
int[] aI=new int[maxL];
int[] bI=new int[maxL];
//结果列
int[] sI=new int[maxL];
//将a填入数组
for (int i = 0; i <aL ; i++) {
aI[maxL-i-1]=supportChar.indexOf(aC[aL-i-1]);
}
//将b填入数组
for (int i = 0; i <bL ; i++) {
bI[maxL-i-1]=supportChar.indexOf(bC[bL-i-1]);
}
//比较aI和bI大小
boolean isMaxA=true;
for (int i = 0; i < maxL; i++) {
if(aI[i]<bI[i]){
isMaxA=false;
break;
}else if(aI[i]>bI[i]){
break;
}
}
for (int i = 0; i < maxL; i++) {
int aS=aI[maxL-i-1];
int bS=bI[maxL-i-1];
if(isMaxA){
//够减,则直接减后的结果作为值
if(aS>=bS){
sI[maxL-i-1]=aS-bS;
}else{
aI[maxL-i-2]-=1;
sI[maxL-i-1]=aS+scale-bS;
}
}else{
if(bS>=aS){
sI[maxL-i-1]=bS-aS;
}else{
bI[maxL-i-2]-=1;
sI[maxL-i-1]=bS+scale-aS;
}
}
}
if(!isMaxA){
//如果a 小于b,则返回负数的结果
return "-"+adjustResult(supportChar, s, sI);
}
//调整返回结果
return adjustResult(supportChar, s, sI);
}
/**
* 检查输入自否合理
* @param a
* @param b
* @param scale
* @param maxScale 最大的进制数
* @param supportChar
*/
private static void checkFormat(String a, String b, int scale, int maxScale, String supportChar) {
if(scale<2||scale>maxScale){
throw new IllegalArgumentException("不支持的进制");
}
//校验字符是否正确,例如2进制,最大数为1,包含2就是错误的输入
for (char c : a.replace(".", "").toCharArray()) {
if(supportChar.indexOf(c)==-1){
throw new IllegalArgumentException("a 输入字符错误");
}
}
for (char c : b.replace(".", "").toCharArray()) {
if(supportChar.indexOf(c)==-1){
throw new IllegalArgumentException("b 输入字符错误");
}
}
}
/**
* 调整返回结果
* @param supportChar 支持的字符
* @param s 小数点后的位数
* @param sI 计算后的结果
* @return
*/
private static String adjustResult(String supportChar, int s, int[] sI) {
StringBuilder sb=new StringBuilder();
char[] charArray = supportChar.toCharArray();
for (int i = 0; i < sI.length; i++) {
sb.append(charArray[sI[i]]);
if(s>0 && sI.length-i==s+1){
sb.append(".");
}
}
String rs = sb.toString();
//去掉小数点后位为0的小数
if(s>0){
while (rs.endsWith("0")&&rs.contains(".")||rs.endsWith(".")){
rs=rs.substring(0,rs.length()-1);
}
}
//去掉首位为0的数
while (rs.length()>1&&rs.startsWith("0")&&rs.indexOf(".")!=1){
rs=rs.substring(1);
}
return rs;
}
}
输出结果为: