高精度运算

高精度加法

先看洛谷的一道高精度加法题:
在这里插入图片描述

public class Demo211555 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String s1 = sc.next();
		String s2 = sc.next();
		//使用ans拼接答案
		StringBuilder ans = new StringBuilder();
		/**
		 * 这里其实我一直有一点疑问,就是这里的40%测试数据是10的18次方,这个数字的长度length
		 * 应该是已经大于int的数据范围了,可为啥我用int来接收 提交代码后仍然能过,
		 * 希望路过的大佬能指点一下,这里先感为敬。
			在了解了查了一些资料以后,发现原来是我的问题,哈哈哈,是我将数字的大小和数字的长度给弄混淆了:
			比如对于10^100次方,这个数字很大吧,long的最大值也就是10^18左右,可见这个数字比long的最大值大多了,可是如果用一个字符串来存储10^100是否能存下呢?答案是肯定可以的,因为:你要注意:字符串在意的不是内容,而是数量,10^100也就能占101位,101可是远远小于int的最大值啊,所以int是足够用的。
		 */
		int l1 = s1.length();
		int l2 = s2.length();
		
		//mod储存了进位
		int mod =0;
		int i=l1-1;
		int j = l2-1;
		//从字符串的尾部逐个相加,再进位
		while(i>=0&&j>=0) {
			int a = s1.charAt(i--) -'0';
			int b = s2.charAt(j--) -'0';
			int tmp = a+b+mod;
			int k = tmp%10;
			ans.append(k);
			mod = tmp/10;
		}
		//如果两个字符串不一样长,就会剩下那个较长的,此时继续加,别忘记可能会有进位:
		if(i<0) {
			while(j>=0) {
				int b = s2.charAt(j--) -'0';
				int tmp = b+mod;
				int k = tmp%10;
				ans.append(k);
				mod = tmp/10;
			}
		}else {
			while(i>=0) {
				int a = s1.charAt(i--)-'0';
				int tmp = a+mod;
				int k = tmp%10;
				ans.append(k);
				mod = tmp/10;
			}
		}
		//这里是个特判,如:300+900 = 1200;
		if(mod !=0) {
			ans.append(mod);
		}
		ans.reverse();
		System.out.println(ans.toString());
	}
}

高精度减法

在这里插入图片描述

public class Demo211629 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String s1 = sc.next();
		String s2 = sc.next();
		int len1 = s1.length();
		int len2 = s2.length();
		//ans用来拼接答案
		StringBuilder ans = new StringBuilder();
		//flag用来标记答案是否是个负数
		boolean flag = false;
		//时刻保持s1大于s2,因为我们习惯用大数减小数,如果有负号后期再做拼接
		if(len1 == len2) {
			if(s1.compareTo(s2)<0) {
				String s3 = s1;
				s1 = s2;
				s2 = s3;
				flag = true;
			}
		}else {
			if(len1<len2) {
				String s3 = s1;
				s1 = s2;
				s2 = s3;
				flag = true;
			}
		}
		//s1,i就对应较大的数
		//s2,j就对应较小的数
		int i = Math.max(len1, len2)-1;
		int j = Math.min(len1, len2)-1;
		int mod =0;
		while(i>=0&&j>=0) {
			int a = s1.charAt(i--) -'0';
			int b = s2.charAt(j--) -'0';
			a+=mod;
			int tmp = 0;
			if(a<b) {
				mod = -1;
				tmp = 10+a-b;
				ans.append(tmp);
			}else {
				mod =0;
				tmp = a-b;
				ans.append(tmp);
			}
		}
		//这里,好多坑的
		//如果第一个数比第二个大很多如:1233333- 455
		//要记得将第一个数的借位给 “借走”
		while(i>=0) {
			int a = s1.charAt(i--) - '0';
			a+=mod;
			int tmp =0;
			if(a<0) {
				mod = -1;
				tmp = 10+a;
			}else {
				mod =0;
				tmp = a;
			}
			ans.append(tmp);
		}
		//将前导0去掉:11- 2 = 09
		int k = ans.length() -1;
		while(ans.length() !=0) {
			if(ans.charAt(k) == '0') {
				ans.deleteCharAt(k--);
			}else {
				break;
			}
		}
		//如果出现相减都是0的情况,再拼接一个0
		if(ans.length() ==0) ans.append(0);
		if(flag)ans.append("-");
		ans.reverse();
		System.out.println(ans.toString());
	}
}

高精度乘法

在这里插入图片描述

public class Demo211728 {
	static int[] c;
	static int[] a;
	static int[] b;
	static int l1,l2,l3;
	static int n = (int)1e6+10;//两个数最大长度也就是10^4000,1e6够用了。
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String s1 = sc.next();
		String s2 = sc.next();
		a = new int[n];
		b = new int[n];
		c = new int[n];
		
		//先将数据倒序存入数组:
		l1 = s1.length();
		l2 = s2.length();
		l3 = l1+l2;
		for(int i =l1 -1;i>=0;i--)a[l1-1-i] = s1.charAt(i) -'0';
		for(int i =l2 -1;i>=0;i--)b[l2-1-i] = s2.charAt(i) -'0';
		
		//处理数据:
		mult(c,a,b);
		//输出结果:
		for(int i =l3-1;i>=0;i--) {
			System.out.print(c[i]);
		}
	}
	private static void mult(int[] c, int[] a, int[] b) {
		// TODO Auto-generated method stub
		for(int i = 0;i<l1;i++) {
			for(int j =0;j<l2;j++) {
				c[i+j]+=a[i]*b[j];
			}
		}
		//处理进位:
		for(int i =0;i<l3;i++) {
			c[i+1] +=c[i]/10;
			c[i]%=10;
		}
		//处理前导0:
		while(l3 >1&&c[l3-1] ==0) l3--;
	}
}

高精度除法

在这里插入图片描述

public class Demo211756 {
	static int n = (int)(1e6+10);
	static int[] c = new int[n];
	static int[] a = new int[n];
	static int lc;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String s1 = sc.next();
		long b =sc.nextLong();
		
		int len =s1.length();
		lc = len;
		//现将a提取出来:
		for(int i =0;i<len;i++) {
			a[i] = s1.charAt(len -i -1)-'0'; 
		}
		
		//
		div(b);
		
		//打印结果:
		for(int i =lc-1;i>=0;i--) {
			System.out.print(c[i]);
		}
		
	}
	private static void div(long b) {
		// TODO Auto-generated method stub
		//这一步真的非常巧妙,点睛之笔。
		
		//这一步必须要将t定义成long,因为如果是9000000000/1000000000这种比较恶心的数据
		//此时就会一直将t累加,如果定义成int就会越界。直到累加到大于b才行,这其实也是除数不能无限大的一个原因,因此此题将b定义小于等于10^9。
		long t =0;
		for(int i =lc;i>=0;i--) {
			t = 10*t+a[i];
			c[i] = (int)(t/b);
			t = (int)(t%b);
		}
		//删掉前导0
		while(lc>1&&c[lc-1] ==0) lc--;
	}
}

java自带高精度运算

唯一的一点感想就是:写完了这些题目以后,发现java原来自带高精度BigInteger,要哭死了。
下面是java高精度写法:

import java.util.*;
import java.math.*;
public class Demo231542 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		BigInteger a = sc.nextBigInteger();
		BigInteger b = sc.nextBigInteger();
		System.out.println(a.add(b));
	}
}

import java.util.*;
import java.math.*;
public class Demo231544 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		BigInteger a = sc.nextBigInteger();
		BigInteger b = sc.nextBigInteger();
		System.out.println(a.subtract(b));
	}
}

import java.util.*;
import java.math.*;
public class Demo231548 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		BigInteger a = sc.nextBigInteger();
		BigInteger b = sc.nextBigInteger();
		System.out.println(a.multiply(b));
	}
}
import java.util.*;
import java.math.*;
public class Demo231549 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		BigInteger a = sc.nextBigInteger();
		if(a.equals(new BigInteger("0"))) {
			System.out.print(0);
			return ;
		}
		BigInteger b = sc.nextBigInteger();
		System.out.println(a.divide(b));
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值