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;
}