整数的四则运算,在编程中是非常常见的。在Java中也是如此,在Java的整形数据类型中较为常用且能存储数值较大的,也只有 int、 long 这两个数据类型,这两个能存储数值的大小范围分别是,int : -2的31次方 ~ +2的31次方减一,long:-2的63次方 ~ +2的63次方减一。
这样的存储范围在日常的计算是肯定够用的了,但是如果需要计算很大的数据范围,直接超出这两个类型所能存储的最大值,那么数据也是会溢出的。
不过Java有专门用于大数计算的API,如BigInteger类等,不过如何实现大数的四则运算,这种思想是可以学习的。
给定两个正整数(不含前导 0),计算它们的和。
数据范围:1 ≤ 整数长度 ≤ 10⁵;
计算方式:
Code
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
// 数值过大,整数类型存放不下
String a=in.next();
String b=in.next();
int lenA=a.length();
int lenB=b.length();
StringBuilder sb=new StringBuilder("");
int sum=0;
int i=lenA-1,j=lenB-1;
// 从最低位开始加
while(i >= 0 || j >= 0){
// 末尾取
int numa=(i == -1) ? 0 : a.charAt(i--)-0x30;
int numb=(j == -1) ? 0 : b.charAt(j--)-0x30;
sum+=(numa+numb);
sb.append(sum%10);
sum/=10;
}
// 表示还需进一位
if(sum != 0){
sb.append(1);
}
System.out.println(sb.reverse().toString());
}
}
给定两个正整数(不含前导 0),计算它们的差,计算结果可能为负数。
数据范围: 1 ≤ 整数长度 ≤ 10⁵;
计算方式:
Code
import java.util.Scanner;
import java.math.BigInteger;
public class Main{
public static boolean cmp(int[] a,int[] b){
if(a.length != b.length) { return a.length > b.length; }
for(int i=a.length-1; i >= 0; --i){
if(a[i] != b[i]) { return a[i] > b[i]; }
}
return true;
}
public static String sub(int[] a,int[] b){
StringBuilder sb=new StringBuilder("");
for(int i=0,t=0; i<a.length; ++i){
// t=a[i]-b[i]-t;
t=a[i]-t;
if(i < b.length) { t-=b[i]; }
// a[i]-b[i] >= 0 ,那么+10%10互相抵消
// < 0 ,那么相等于a[i]-b[i]+10,+10等于借位,再%10
sb.append((t+10)%10);
// 借位判断
if(t < 0) { t=1; }
else { t=0; }
}
// 去除前导0
String s=sb.reverse().toString();
int i=0;
for(int end=s.length()-1; i<end; ++i){
if(s.charAt(i) != '0') break;
}
return s.substring(i,s.length());
}
public static void main(String[] args){
Scanner in=new Scanner(System.in);
String a=in.next(); // 3 2
String b=in.next(); // 1 1
int[] arrA=new int[a.length()];
int[] arrB=new int[b.length()];
for(int i=arrA.length-1; i>=0; --i)
{ arrA[arrA.length-1-i]=a.charAt(i)-0x30; }
for(int i=arrB.length-1; i>=0; --i)
{ arrB[arrB.length-1-i]=b.charAt(i)-0x30; }
// 使用保证计算时 a > b
if(cmp(arrA,arrB) ){
System.out.print(sub(arrA,arrB));
}else{
System.out.print("-"+sub(arrB,arrA));
}
}
}
给定两个非负整数(不含前导 0) A 和 B,请你计算 A×B的值。
数据范围: 1 ≤ A的长度 ≤ 10⁵,0 ≤ B ≤ 10000
计算方式:
Code
import java.util.Scanner;
public class Main{
public static String process(int[] nums,int b){
StringBuilder sb=new StringBuilder();
int t=0;
for(int i=0; i<nums.length || t != 0; ++i){
// int num=nums[i]*b+t;
// sb.append(num%10);
// t+=num/10;
if(i < nums.length) t+=nums[i]*b;
sb.append(t%10);
t/=10;
}
return sb.reverse().toString();
}
public static void main(String[] args){
Scanner in=new Scanner(System.in);
String numA=in.next();
int numB=in.nextInt();
if(0 == numB) {
System.out.print(0);
return;
}
int[] nums=new int[numA.length()];
for(int i=nums.length-1,j=0; i>=0; --i,++j){
nums[j]=numA.charAt(i)-0x30;
}
System.out.print(process(nums,numB));
}
}
给定两个非负整数(不含前导 0) A,B,请你计算 A/B的商和余数。
数据范围: 1 ≤ A的长度 ≤ 10⁵ , 1 ≤ B ≤ 10000 , B 一定不为 0
计算方式:
Code
import java.util.Scanner;
public class Main{
static int r;
// r是余数
public static String div(int[] nums,int b){
StringBuilder sb=new StringBuilder();
r=0;
// 从高位往地位走
for(int i=nums.length-1; i >= 0; --i){
r=r*10+nums[i]; // 将剩下的数取下来
sb.append(r/b); // 计算商
r%=b; // 计算余数
}
// 去除前导零
int i=0;
int len=sb.length();
while(i < len && sb.charAt(i) == '0'){
++i;
}
if(i == len) { return "0"; }
return sb.substring(i);
}
public static void main(String[] args){
Scanner in=new Scanner(System.in);
String numA=in.next();
int numB=in.nextInt();
if(0 == numB) {
System.out.print(0);
return;
}
int[] nums=new int[numA.length()];
for(int i=nums.length-1,j=0; i>=0; --i,++j){
nums[j]=numA.charAt(i)-0x30;
}
System.out.println(div(nums,numB));
System.out.println(r);
}
}