1.大数加法:
注意加法需要判断最高位的下一位!!!
☞ C语言实现:
这种方法定义了太多数组,它的实现核心与阶乘相似。
#include<stdio.h>
#include<iostream>
using namespace std;
int main(){
int arr[1010];
int brr[1010];
int crr[2000];
string sa,sb;
cin>>sa>>sb;
for(int i=0;i<sa.size();i++)///注意这里下表是反过来算的
arr[i]=sa[sa.size()-i-1]-48;
for(int i=0;i<sb.size();i++)
brr[i]=sb[sb.size()-i-1]-48;
int lenc = max(sa.size(),sb.size());
int num=0;
for(int i=0;i<lenc;i++){
int temp=arr[i]+brr[i]+num;
crr[i]=temp%10;
num=temp/10;
}
if(num)///最高位的下一位如果不为0,肯定为1
crr[lenc]=1;
if(num) for(int i=lenc;i>=0;i--) cout<<crr[i];
else for(int i=lenc-1;i>=0;i--) cout<<crr[i];
}
☞ C语言实现改进版:
#include<stdio.h>
#include<iostream>
using namespace std;
int main(){
int arr[10010];
int brr[10010];
string sa,sb;
cin>>sa>>sb;
for(int i=0;i<sa.size();i++)///注意这里下表是反过来算的
arr[i]=sa[sa.size()-i-1]-48;///也可以sa[sa.size()-i-1]-'0'
for(int i=0;i<sb.size();i++)
brr[i]=sb[sb.size()-i-1]-48;
int lenc = max(sa.size(),sb.size());
for(int i=0;i<lenc;i++) arr[i]=arr[i]+brr[i];///对应的每一位先全部加到a数组
for(int i=0;i<lenc;i++){
arr[i+1]=arr[i+1]+arr[i]/10;
arr[i]=arr[i]%10;
}
if(arr[lenc]) for(int i=lenc;i>=0;i--) cout<<arr[i];
else for(int i=lenc-1;i>=0;i--) cout<<arr[i];
}
☞ Java语言实现:
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
BigInteger a = sc.nextBigInteger();
BigInteger b = sc.nextBigInteger();
BigInteger c = a.add(b);
System.out.println(c);
}
}
虽然Java中有BigInteger对象可以定义超大数据,但是我们一般能不调用就不调用,为了提高程序效率。
import java.util.*;
public class Main {
public static void main(String [] args) {
Scanner sc = new Scanner(System.in);
String stra = sc.next();
String strb = sc.next();
int len=Math.max(stra.length(),strb.length());
int arr[] = new int[len+1];
int brr[] = new int[len];
for(int i=0;i<stra.length();i++)
arr[i]=Integer.valueOf(stra.charAt(stra.length()-1-i)-48);
for(int i=0;i<strb.length();i++)
brr[i]=Integer.valueOf(strb.charAt(strb.length()-1-i)-48);
for(int i=0;i<len;i++) arr[i]=arr[i]+brr[i];
for(int i=0;i<len;i++) {
arr[i+1]=arr[i+1]+arr[i]/10;
arr[i]=arr[i]%10;
}
if(arr[len]!=0) for(int i=len;i>=0;i--) System.out.print(arr[i]);
else for(int i=len-1;i>=0;i--) System.out.print(arr[i]);
}
}
2.大数减法
减法分两种情况:分清楚被减数和减数大小的先后和不分被减数和减数的大小先后
以不分被减数和减数的大小先后为例,由于大数用字符表示,所以我们可以从位数和大小考虑:
- 两数位数不同:位数大的数减去位数小的数
- 两数位数相同,但大小不同:从最高位开始比较,一位一位地比。
注意问题: 防止输出会有0的情况,因为得到的最终数可能比两数中都要小。
#include<stdio.h>
#include<iostream>
using namespace std;
int main(){
int arr[10010];
int brr[10010];
string sa,sb;
cin>>sa>>sb;
int lena = sa.size();
int lenb = sb.size();
for(int i=0;i<lena;i++)///注意这里下标是反过来算的
arr[i]=sa[lena-i-1]-48;
for(int i=0;i<lenb;i++)
brr[i]=sb[lenb-i-1]-48;
bool flag=false;
if(lena<lenb) flag = true;///判断两数大小
else if(lena==lenb){
for(int i=lena-1;i>=0;i--){
if(arr[i]<brr[i]) flag =true;///从后面返回遍历,在两数相同位的情况下,如果arr当前位小于brr当前位,说明arr数小于b数
}
}///其他情况为false
int sum[10010]={0};
int j;
if(flag){
for(j=0;j<lenb;j++)
sum[j] = brr[j]-arr[j];///先全部位对应减去
for(j=0;j<lenb;j++)
if(sum[j]<0&&j+1<lenb){
sum[j]+=10;
sum[j+1]--;
}
}else {
for(j=0;j<lena;j++)
sum[j] = arr[j]-brr[j];
for(j=0;j<lena;j++)
if(sum[j]<0&&j+1<lena){
sum[j]+=10;
sum[j+1]--;
}
}
int k=j-1;
while(sum[k]==0) k--;///去掉最高位出现0的情况
for(int i=k;i>=0;i--) cout<<sum[i];
}
3. 大数阶乘:
import java.util.*;
public class Main {
public static void main(String [] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int maxx=4000;
int []arr = new int[maxx];
arr[0]=1;
int temp;
for(int i=2;i<=n;i++){
int num=0;
for(int j=0;j<maxx;j++){
temp = arr[j]*i+num;
arr[j] = temp%10;///储存当前位的数
num = temp/10;
}
}
int k;
for(k=maxx-1;k>=0;k--) if(arr[k]!=0) break;
for(int j=k;j>=0;j--) System.out.print(arr[j]);
}
}
3.大数除法
大数除法分为两种情况:
- 从输入情况:一是高精度除以低精度(大数除小数),一是高精度除以高精度(大数除以大数)
- 从输出情况:一是求商(取模),一是求余(取余)。
基本思想是反复做除法,看从被除数里面最多能减去多少个除数,商就是多少(下面的数组crr)。把除数增大到与被除数一样的位数(除数小于被除数,除数加0),如130/5,商的位数必定为两数位数差(针对于大数除以大数),除数增大到500,130/500,除数大于被除数,除数要减小,130/50,商的十位加1…
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int arr[1010]; //被除数
int brr[1010]; //除数
int crr[1010]; //商
char stra[1010]; //读入的第一个大数
char strb[1010]; //读入的第二个大数
int jianfa( int *x, int *y, int lena, int lenb )
{
int i;
if( lena < lenb )
return -1;
if( lena == lenb )
{
for( i=lena-1; i>=0; i-- )
{
if( x[i] > y[i] )
break;
else if( x[i] < y[i] )
return -1;
}
}
for( i=0; i<lena; i++ ) //从低位开始做减法
{
x[i] =x[i]-y[i];
if( x[i] < 0 ) //若x[i]<0,则需要借位
{
x[i] += 10; //借1当10
x[i+1]--; //高位减1
}
}
for( i=lena-1; i>=0; i-- ) //查找结果的最高位
if( x[i] ) //最高位第一个不为0
return (i+1); //得到位数并返回
return 0; //两数相等的时候返回0
}
int main()
{
int n, k, i, j; //n:测试数据组数
int lena, lenb; //大数位数
scanf("%s %s", stra,strb); //以字符串形式读入大数
lena = strlen(stra); //获得大数的位数
lenb = strlen(strb);
int len,temp;
for( j=0, i=lena-1; i>=0; j++, i-- )
arr[j] = stra[i] - '0'; //将字符串转换成对应的整数,颠倒存储
for( j=0, i=lenb-1; i>=0; j++, i-- )
brr[j] = strb[i] - '0';
if( lena < lenb ) {//如果被除数小于除数,结果为0
printf("商:0\n");
printf("余:%s",stra);
puts("");
return;
}
len = lena - lenb; //相差位数
for ( i=lena-1; i>=0; i-- ) //将除数扩大,使得除数和被除数位数相等
{
if ( i>=len )
brr[i] = brr[i-len];
else //低位置0
brr[i] = 0;
}
lenb = lena;
for( j=0; j<=len; j++ ) //不断减数,记录减成功的次数,即为商
{
while((temp = jianfa(arr,brr+j,lena,lenb-j)) >= 0)///
{
lena = temp; //更新被除数位数
crr[len-j]++;//每成功减一次,将商的相应位加1
}
}
k=len-1;
while(crr[k]==0) k--;
printf("商:");
if(k>=0){
for(i=k; i>=0; i-- ) printf("%d", crr[i]);
}
else printf("0");
int ka = lena-1;
while(crr[ka]==0) ka--;
printf("\n余:");
if(ka>=0){
for(i=ka; i>=0; i-- ) printf("%d", crr[i]);
}
else printf("0");
return 0;
}
下面的方法只能用于高精度除以低精度
4.大数的幂运算
此法跟乘法一样,只不过相乘的是自身。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100///按题目需求
int num[MAX];
char str[MAX];
int arr[MAX*MAX];
void chengfa(int num[],int arr[],int len){
int s[MAX*MAX]={0};
for(int i=0;i<len;i++)
for(int j=0;j<MAX*MAX;j++)///由于自乘可能超出原数字串的长度
s[i+j]=s[i+j]+num[i]*arr[j];///每一位各自相乘
for(int i=0;i<MAX*MAX;i++){
if(s[i]>=10) s[i+1]=s[i+1]+s[i]/10;
arr[i]=s[i]%10;
}
}
int main(){
int n;
scanf("%s %d",str,&n);
int len = strlen(str);
int a=0,b=0;
for(int i=len-1;i>=0;i--)
{
num[a++]=str[i]-'0';
arr[b++]=str[i]-'0';
}///注意这里与上面不同,要各自定义下标
n--;
while(n){///不断自乘,直到幂数为0
chengfa(num,arr,len);
n--;
}
int k=MAX*MAX-1;
while(arr[k]==0) k--;
printf("%d\n",k);
for(int i=k;i>=0;i--) printf("%d",arr[i]);
printf("\n");
return 0;
}