java简单方法实现不限制数字长度的加减乘除计算器/适合新手小白

一般计算器都有长度限制,想做一个突破int,long范围的计算器,我是新手,所以用了非常简单非常笨的一个方法。

在家看到小孩做作业列竖式,就想能不能用列竖式的逻辑来做一个简易计算器,思路也很简单,int类型有长度限制,String没有啊,用String类型来存储数字,把String一个一个拆分为char,然后再做逻辑运算,最后还是用String类型存储结果

目前只粗糙的写了一个加法和乘法,后续如果会考虑把减法和除法加上,以及代码优化

以下是代码,注释的很详细,欢迎大家批评指正

最好做的就是加法跟减法了

加减乘除都有了,功能还需完善,后续会继续补充

/**
	 * 
	 * 加法
	 * 
	 * @param num1
	 * @param num2
	 * @return
	 */
	public String add(String num1, String num2) {

		// 将字符串拆分为char数组
		char[] ch1 = num1.toCharArray();
		char[] ch2 = num2.toCharArray();

		// result用来存储结果,flag用来标记“满10进1”
		StringBuffer result = new StringBuffer();
		boolean flag = false;

		// 循环条件选用长度更长的参数的length,
		for (int a = 1; a <= (ch1.length > ch2.length ? ch1.length : ch2.length); a++) {
			int i = 0;
			int j = 0;
			if (ch1.length - a >= 0) {// 加if判断防止数组下标越界
				i = ch1[ch1.length - a] - '0';// 将char转换为int
			}
			if (ch2.length - a >= 0) {
				j = ch2[ch2.length - a] - '0';
			}

			int n = (i + j) % 10;// 取余数,用于result存储

			if (flag) {// 满足“满10加1”的操作
				result.append((n + 1) == 10 ? 0 : (n + 1));
				if ((i + j + 1) >= 10) {
					flag = true;
				} else {
					flag = false;
				}
			} else {// 不满足“满10 加1”的操作
				result.append(n);
				if ((i + j) >= 10) {
					flag = true;
				} else {
					flag = false;
				}
			}

		}
		if (flag) {// 最后需再次判断“满10加1”
			result.append(1);
		}
		result.reverse();// 将result反转过来就是最终结果
		// System.out.println("加法结果" + result);
		return result.toString();
	}

减法:将加法稍微变动一下,目前能得到负数,但是还不支持负数作为参数,后续会考虑

	/**
	 * 减法
	 * 
	 * @param num1
	 * @param num2
	 * @return
	 */
	public String sub(String num1, String num2) {
		// 将字符串拆分为char数组
		char[] ch1 = num1.toCharArray();
		char[] ch2 = num2.toCharArray();

		StringBuffer result = new StringBuffer();
		boolean flag = false;

		int k = compare(num1, num2);
		char[] chTemp;
		if (k < 0) {
			chTemp = ch1;
			ch1 = ch2;
			ch2 = chTemp;
		} else if (k == 0) {
			return "0";
		}

		for (int a = 1; a <= (ch1.length > ch2.length ? ch1.length : ch2.length); a++) {
			int i = 0;
			int j = 0;
			if (ch1.length - a >= 0) {// 加if判断防止数组下标越界
				i = ch1[ch1.length - a] - '0';// 将char转换为int
			}
			if (ch2.length - a >= 0) {
				j = ch2[ch2.length - a] - '0';
			}

			int n = 0;
			if (flag) {
				if ((i = i - 1) >= j) {
					n = i - j;
					flag = false;
				} else {
					n = i + 10 - j;
					flag = true;
				}

			} else {
				if (i >= j) {
					n = i - j;
					flag = false;
				} else {
					n = i + 10 - j;
					flag = true;
				}
			}

			result.insert(0, n);
		}

		while (result.indexOf("0") == 0) {
			if (result.length() > 1) {
				result = result.deleteCharAt(0);
			} else {
				break;
			}
		}

		if (k < 0) {
			result.insert(0, "-");
		}

		return result.toString();
	}

乘法:已经添加了计算小数的功能

	/**
	 * 
	 * 乘法
	 * 
	 * @param num1
	 * @param num2
	 * @return
	 */
	public String mul(String num1, String num2) {

		// 判断是否为小数
		int indexnum1 = num1.indexOf(".");
		int indexnum2 = num2.indexOf(".");
		// point用来记录小数位数
		int point = 0;
		// if判断用来计算小数点后的小数位
		if (indexnum1 >= 0) {
			point = point + num1.length() - indexnum1 - 1;
		}
		if (indexnum2 > 0) {
			point = point + num2.length() - indexnum2 - 1;
		}

		// 将小数点去除
		num1 = num1.replace(".", "");
		num2 = num2.replace(".", "");

		// 将字符串拆分为char数组
		char[] ch1 = num1.toCharArray();
		char[] ch2 = num2.toCharArray();

		// 存储下面内层for循环产生的单次结果,用来计算最终结果
		List<StringBuffer> list = new ArrayList<StringBuffer>();
		for (int i = 1; i <= ch1.length; i++) {
			int n1 = ch1[ch1.length - i] - '0';// 将char转换为int
			int s = 0;// 用来存储需要进位的十位数

			StringBuffer result = new StringBuffer();

			for (int j = 1; j <= ch2.length; j++) {
				int n2 = ch2[ch2.length - j] - '0';// 将char转换为int
				int m = (n1 * n2) % 10;// 取个位数
				// 三目判断如果满10取个位数,存入到result中
				result.insert(0, (m + s) >= 10 ? (m + s) % 10 : (m + s));
				s = (n1 * n2 + s) / 10;// 取十位数,用作进位
			}
			if (s > 0) {// 内层for每次循环完毕,需判断是否需要进位
				result.insert(0, s);
			}

			// while方法是为了乘数为零的情况下,避免最终结果为多个0 的情况(如果最终结果为多个0 ,就将它改为一个0)
			while (result.indexOf("0") == 0) {
				if (result.length() > 1) {
					result = result.deleteCharAt(0);
				} else {
					break;
				}
			}
			// System.out.println("乘法单次结果" + result);
			list.add(result);// 将单次结果存储到list中

		}

		// result用来存储最终结果
		StringBuffer result = new StringBuffer();
		// str用来存储单次结果或者调用add方法后的结果的最末尾的数字,最后会被result使用
		StringBuffer str = new StringBuffer();
		// add用来存储调用add方法返回的数据
		String add = null;

		// if判断list长度,长度为1 说明至少有一个乘数为个位数,则只需记录单次结果,即list.get(0)
		if (list.size() > 1) {
			for (int i = 0; i < list.size() - 1; i++) {
				String s1 = "";// 用作存储第一个加数
				if (add != null) {
					// 截取末尾数字,存储到str,因为每次的末尾数字不需要相加,只需保存,最后交给result使用
					String st = add.substring(add.length() - 1, add.length());
					str.insert(0, st);
					s1 = add.substring(0, add.length() - 1);// 第一个加数
				} else {// 第一次循环时候会走else,因为还没有add的数据
					result = list.get(i);
					String st = list.get(i).substring(list.get(i).length() - 1,
							list.get(i).length());
					str.insert(0, st);
					s1 = result.substring(0, result.length() - 1);// 第一个加数
				}
				String s2 = list.get(i + 1).toString();// 获取第二个加数
				add = add(s1, s2);// 调用add方法,返回结果存储到add字符串中,用于下次循环使用
			}
		} else {
			str = list.get(0);
		}

		// 如果add不为空,取add的值
		if (add != null) {
			result = new StringBuffer(add);// 将add结果存储
		}
		result.append(str);// 最终结果

		// while方法是为了乘数为零的情况下,避免最终结果为多个0 的情况(如果最终结果为多个0 ,就将它改为一个0)
		while (result.indexOf("0") == 0) {
			if (result.length() > 1) {
				result = result.deleteCharAt(0);
			} else {
				break;
			}
		}

		//加上小数点,需先用0补位,避免出现.前面没有0,或数组下标越界
		if (point != 0) {
			if (result.length() - 1 < point) {
				int pointTemp = point - result.length() + 1;
				for (int i = 0; i < pointTemp; i++) {
					result.insert(0, "0");
				}
			}
			result.insert(result.length() - point, ".");
		}

		//小数点后如果只有0,省略掉;如88.00省略为88
		while (result.lastIndexOf(".") > 0 && result.lastIndexOf("0") == result.length() - 1) {
			result.deleteCharAt(result.length() - 1);
			if (result.lastIndexOf(".") == result.length() - 1) {
				result.deleteCharAt(result.length() - 1);
				break;
			}
		}

		// System.out.println("乘法结果" + result);
		return result.toString();
	}

除法:做起来才知道除法最难了~,目前只是一个雏形,后续会补充和优化,就先不加注释了
目前能够得到小数 只支持正整数运算

	/**
	 * 除法
	 * 
	 * 目前只支持正整数运算
	 * 可以得到小数结果
	 * 最大结果长度暂定1000
	 * 
	 * @param num1
	 * @param num2
	 * @return
	 * 
	 */
	public String div(String num1, String num2) {
		num1 = this.trim(num1);
		num2 = this.trim(num2);
		
		if(num2.equals("0")){
			return "除数不能为0!";
		}
		
		// result存储结果
		StringBuffer result = new StringBuffer();

		// 临时被除数
		String num1Temp = num1;
		//存储被除数取余除数的结果
		String sub = "";
		//用于标记添加小数点操作
		boolean flag = false;
		//用于存储一位得到的商(商是一位一位得到的)
		int temp = -1;
		for (int i = 0;; i++) {
			if (i + 1 <= num1.length()) {
				if (sub.equals("")) {
					num1Temp = num1.substring(0, i + 1);
				} else {
					num1Temp = sub + num1.substring(i, i + 1);
				}
			} else {
				num1Temp = num1Temp + 0;
				if (flag == false) {
					result.append(".");
					flag = true;
				}
			}
			//比较临时被除数和除数的大小
			int k = compare(num1Temp, num2);
			if (k > 0) {
				// for循环得到商的一位数字
				for (int j = 2;; j++) {
					int comp = compare(num1Temp, mul(num2, j + ""));
					if (comp < 0) {
						temp = j - 1;
						result.append(temp);
						break;
					} else if (comp == 0) {
						temp = j;
						result.append(temp);
						break;
					}

				}
				//取余
				sub = sub(num1Temp, mul(num2, temp + ""));
				//设置被除数
				num1Temp = sub;
				if (sub.equals("0") && i >= num1.length() - 1) {
					break;
				}
				// 测试用,保留1000长度
				if (result.length() == 1000) {
					break;
				}

			} else if (k < 0) {
				result.append(0);
			} else {
				result.append(1);
				sub = "0";
				if (i >= num1.length() - 1) {
					break;
				}
			}

		}
		// 去除result中无效的0,如008,改为8
		while (result.indexOf("0") == 0 && result.indexOf("0.") != 0) {
			if (result.length() > 1) {
				result = result.deleteCharAt(0);
			} else {
				break;
			}
		}

		return result.toString();
	}

公共方法:用于比较两个数的大小,支持比较小数

	/**
	 * 
	 * 公共方法
	 * 比较两个数字的大小
	 * 目前只能是正数,整数和小数都可以
	 * 
	 * @param ch1
	 * @param ch2
	 * @return
	 */
	public int compare(String str1, String str2) {

		str1 = this.trim(str1);
		str2 = this.trim(str2);

		if (str1.contains(".")||str2.contains(".")) {
			String[] ch1 = str1.split("\\.");
			String[] ch2 = str2.split("\\.");
			int comp = this.compare2(ch1[0], ch2[0]);
			if(comp!=0){
				return comp;
			}
			int com = this.compare3(ch1.length==2?ch1[1]:"0",ch2.length==2?ch2[1]:"0");
			return com;
		}
		int comp = this.compare2(str1, str2);
		return comp;
	}

	/**
	 * private方法
	 * 比较大小(小数中的整数部分)
	 * 用于compare()调用
	 * 
	 * @param str1
	 * @param str2
	 * @return
	 */
	private int compare2(String str1, String str2) {

		if (str1.length() > str2.length()) {
			return 1;
		} else if (str1.length() < str2.length()) {
			return -1;
		} else {
			for (int i = 0; i < str1.length(); i++) {
				int ch1=str1.charAt(i)-'0';
				int ch2=str2.charAt(i)-'0';
				if (ch1 > ch2) {
					return 1;
				} else if (ch1 < ch2) {
					return -1;
				}
			}
		}

		return 0;
	}

	/**
	 * private方法
	 * 比较大小(小数中的小数部分)
	 * 用于compare()调用
	 * 
	 * 代码有点冗余,后续再优化
	 * 
	 * @param str1
	 * @param str2
	 * @return
	 */
	private int compare3(String str1, String str2) {

		
		if (!str1.equals(str2)) {
			boolean flag = str1.length() > str2.length();

			if (flag) {
				for (int i = 0; i < str1.length(); i++) {
					int ch1=str1.charAt(i)-'0';
					int ch2=str2.charAt(i)-'0';
					if (ch1 > ch2) {
						return 1;
					} else if (ch1 < ch2) {
						return -1;
					}
				}
				return 1;
			}
			
			if (!flag) {
				for (int i = 0; i < str1.length(); i++) {
					int ch1=str1.charAt(i)-'0';
					int ch2=str2.charAt(i)-'0';
					if (ch1 > ch2) {
						return 1;
					} else if (ch1 < ch2) {
						return -1;
					}
				}
				return -1;
			}
			
			if(str1.length()==str2.length()){
				for (int i = 0; i < str1.length(); i++) {
					int ch1=str1.charAt(i)-'0';
					int ch2=str2.charAt(i)-'0';
					if (ch1 > ch2) {
						return 1;
					} else if (ch1 < ch2) {
						return -1;
					}
				}
				return 0;
			}
			
			
		}
		return 0;
	}

trim方法:用于去掉首尾无效的0

	/**
	 * 公共方法 去除首尾无效的0
	 * 
	 * 
	 * @param str
	 * @return
	 */
	public String trim(String str) {
		// 去掉数字前面无效的0,如008省略为8
		while (str.startsWith("0") && !str.startsWith("0.")) {
			if (str.length() > 1) {
				str = str.substring(1, str.length());
			}
		}
		// 小数点后如果只有0,省略掉;如88.00省略为88
		while (str.indexOf(".") > 0 && str.endsWith("0")) {
			str = str.substring(0, str.length() - 1);
			if (str.lastIndexOf(".") == str.length() - 1) {
				str = str.substring(0, str.length() - 1);
				break;
			}
		}
		return str;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值