高精度运算

加法

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

int main() {
	string a, b;
	int i = 0, j;
	int f = 0;//是否产生进位
	int ans[510];
	cin >> a >> b;
	reverse(a.begin(), a.end());
	reverse(b.begin(), b.end());

	string temp;
	//保证大数a的长度>=b的长度
	if (a.length() < b.length()) {
		temp = a;
		a = b;
		b = temp;
	}
	for (i = 0; i < b.length(); i++) {
		int temp = (a[i] - '0') + (b[i] - '0') + f;
		ans[i] = temp % 10;
		if (temp >= 10) {
			f = 1;
		}
		else {
			f = 0;
		}
	}
	if (a.length() > b.length()) {
		while (i < a.length()) {
			int temp = (a[i] - '0') + f;
			ans[i] = temp % 10;
			if (temp >= 10) {
				f = 1;
			}
			else {
				f = 0;
			}
			i++;
		}
	}
	if (f == 1) {
		cout << f;
	}
	for (j = i - 1; j >= 0; j--) {
		cout << ans[j];
	}
	return 0;
}

减法

#include<iostream>
#include<string>
#include<algorithm>

using namespace std;

#define maxsize 10100
//比较大小   1:a大  2:b大
int compare(string a, string b) {
	int flag = 0;
	if (a.length() > b.length()) {
		return 1;
	}
	else if(a.length() < b.length()){
		return 2;
	}
	else {
		//长度相等,未逆转,直接比较,低位即数值高位
		for (int i = 0; i < a.length(); i++) {
			if (a[i] > b[i]) {
				flag = 1;
				return 1;
			}
			else if (b[i] > a[i]) {
				flag = 1;
				return 2;
			}
		}
	}
	if (flag == 0) {
		return 0;//相等
	}
}
int main() {
	string a, b;
	int i = 0, j;
	int f = 0;//是否产生借位
	int ans[maxsize];

	cin >> a >> b;
	int c = compare(a, b);

	//a、b相等
	if (c == 0) {
		cout << "0" << endl;
		return 0;
	}
	//若b比a大,先输出一个负号,交换a,b
	if (c == 2) {
		cout << "-"; 
		swap(a, b);
	}
	
	reverse(a.begin(), a.end());
	reverse(b.begin(), b.end());

	int atemp, btemp;
	for (i = 0; i < b.length(); i++) {
		atemp = a[i] - '0';
		btemp = b[i] - '0';
		if (atemp - f - btemp < 0) {			
			ans[i] = atemp + 10 - f - btemp;
			f = 1;
		}
		else {			
			ans[i] = atemp - f - btemp;
			f = 0;
		}
		
	}
	if (a.length() > b.length()) {
		while (i < a.length()) {
			atemp = a[i] - '0';
			if (atemp - f < 0) {				
				ans[i] = atemp + 10 - f;
				f = 1;
			}
			else {				
				ans[i] = atemp - f;
				f = 0;
			}
			i++;
		}
	}
	int zero = 0;
	//3330000000000000
	//3320000000000000
	//0010000000000000前面的0不能输出
	for (j = i - 1; j >= 0; j--) {
		if (ans[j] != 0) {
			zero = 1;
		}//前面的0不输出
		if (zero) {
			cout << ans[j];
		}
		
	}

	return 0;
}

乘法

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

int c[5001];
int ans[5001];
int main() {	
	string a, b;		
	cin >> a >> b;
	//a,b中有0
	if ((a.length() == 1 && a[0] == '0') || (b.length() == 1 && b[0] == '0')) {
		cout << "0";
		return 0;

	}
	reverse(a.begin(), a.end());
	reverse(b.begin(), b.end());
	int f, f2, i, j, k, m;
	//f乘法进位,f2每位结果相加进位
	int prel,length;
	//循环,每一位被乘数
	for (i = 0; i < b.length(); i++) {
		f = 0;
		k = 0;
		int b1 = b[i] - '0';//取一位乘数
		int wei = i;
		while (wei--) { //高位乘要补0,第二位补1个0
			c[k++] = 0;
		}
		//与被乘数每一位相乘
		for (j = 0; j < a.length(); j++) {
			int a1 = a[j] - '0';	
			if (a1 * b1 + f < 10) {
				c[k] = a1 * b1 + f;
				f = 0;
			}
			else {
				c[k] = (a1 * b1 + f) % 10;
				f = (a1 * b1 + f) / 10;
			}	
			k++;
		}
		//最后一位的进位
		if (f != 0) {
			c[k++] = f;
		}
		// 乘数第一位乘被乘数的结果赋给ans,方便后期相加
		if (i == 0) {  
			for (m = 0; m < k; m++) {
				ans[m] = c[m];
			}
			prel = k;//前一个结果的长度
		}
		else {			
			m = 0; f2 = 0;
			while (m < prel) {			
				if (ans[m] + c[m] + f2 < 10){
					ans[m] = ans[m] + c[m] + f2;
					f2 = 0;
				}
				else {
					int tt = f2; //否则会对ans值有影响
					f2 = (ans[m] + c[m] + f2) / 10;
					ans[m] = (ans[m] + c[m] + tt) % 10;
					
				}	
				m++;
			}
			if (prel != k ){
				while (m < k) {
					if (c[m] + f2 <10) {
						ans[m] = c[m] + f2;
						f2 = 0;						
					}
					else {
						int tt = f2;
						f2 = (c[m] + f2) / 10;
						ans[m] = (c[m] + tt) % 10;						
					}
					m++;
				}				
			}
			if (f2 != 0) {
				ans[m++] = f2;
			}
			prel = m;	
		}
	}	
	for (int w = prel-1; w >= 0; w--) {
		cout << ans[w];
	}
	cout << endl;	
	return 0;
}

除法(高精度/单精度)

#include<iostream>
#include<string>
//高精度/低精度
using namespace std;
#define maxsize 5010

//
int main() {
	string a;
	int b;
	int i, j;
	int ans[maxsize];
	cin >> a >> b;

	if (a.length() == 1 && a[0]-'0' == 0) {
		cout << "0" << endl;
		return 0;
	}
	int temp = 0;
	j = 0;
	for (i = 0; i < a.length(); i++) {
		int t = a[i] - '0';
		temp = temp * 10 + t;
		if (temp >= b) {
			//cout << temp << endl;
			ans[j] = temp / b;
			temp = temp % b;
			//cout << ans[j] << " " << temp << endl;
		}
		else {
			ans[j] = 0;
		}
		j++;
	}
	int zero = 0;
	//cout << temp << endl;
	for (i = 0; i < j; i++) {
		if (ans[i] != 0) {
			zero = 1;
		}
		if (zero) {
			cout << ans[i];
		}
	}
	return 0;
}

除法(高精度/高精度)

搬运工

#include <iostream>
#include <cstring>
using namespace std;

//去除前导0
int delPreZero(int x[], int xLen) {
    int i = xLen;

    while (x[i - 1] == 0 && i > 1) {
        i--;
    }

    return i;
}

//逆序输出数组值 
void printArr(int x[], int xLen) {
    for (int i = xLen - 1; i >= 0; i--) {
        cout << x[i];
    }
    cout << endl;
}

//若x>=y返回true,否则返回false 
bool compare(int x[], int y[], int xLen, int yLen) {
    if (xLen < yLen) {
        return false;
    }


    if (xLen == yLen) {
        for (int i = xLen - 1; i >= 0; i--) {
            if (x[i] > y[i]) {
                return true;
            }
            if (x[i] < y[i]) {
                return false;
            }
        }
        return true;
    }
    return true;
}

//若x>=y,则x的高位减去y(只减一次),返回值为x的新长度
int sub(int x[], int y[], int z[], int xLen, int yLen) {
    int zLoc = xLen - yLen;    //商的位置 

    //若不够减,则商的位置后移一位 
    for (int i = 1; i <= yLen; i++) {
        if (x[xLen - i] > y[yLen - i])
            break;

        if (x[xLen - i] < y[yLen - i]) {
            zLoc--;
            break;
        }
    }

    if (zLoc < 0)
        return xLen;

    //当前被除数x的高位与除数y做一次减法运算 
    for (int i = zLoc, j = 0; i < xLen && j < yLen; i++, j++) {
        while (x[i] < y[j]) {
            x[i + 1]--;
            x[i] += 10;
        }

        x[i] -= y[j];
    }

    //商的相应位置加一 
    z[zLoc]++;

    //计算当前被除数x的真实长度 
    while (x[xLen - 1] == 0)
        xLen--;

    if (xLen <= 0)
        xLen = 1;

    return xLen;
}

int main() {
    char as[301], bs[301];

    int a[301] = { 0 }, b[301] = { 0 }, c[301] = { 0 };
    int aLen = 0, bLen = 0, cLen = 1, maxLen = 0;
    int i;

    //输入 
    cin >> as >> bs;
    aLen = strlen(as);
    bLen = strlen(bs);

    //被除数和除数分别逆序存放 
    for (i = 0; i < aLen; i++) {
        a[i] = as[aLen - 1 - i] - '0';
    }

    for (i = 0; i < bLen; i++) {
        b[i] = bs[bLen - 1 - i] - '0';
    }

    //去除前导0
    aLen = delPreZero(a, aLen);
    bLen = delPreZero(b, bLen);

    //通过从高位开始连续减去除数,计算商和余数 
    cLen = aLen - bLen + 1;
    while (compare(a, b, aLen, bLen)) {
        aLen = sub(a, b, c, aLen, bLen);
    }

    //解决商的位数是0或负数的情况 
    if (cLen < 1) {
        cLen = 1;
    }

    //去除商的前导0 
    cLen = delPreZero(c, cLen);

    //输出商c 
    printArr(c, cLen);

    //输出余数a 
    printArr(a, aLen);

    return 0;
}

P1009 阶乘之和

用高精度计算出S=1!+2!+3!+…+n! (n≤50)S=1!+2!+3!+…+n!(n≤50)

#include<iostream>

using namespace std;
int a[2000];
int b[2000];
int c[2000];
int sum[2000];

void pplus(int* a, int* c)
{
    int jw = 0;
    for (int i = 1; i <= 1000; i++)
    {
        c[i] += a[i] + jw;
        jw = c[i] / 10;
        c[i] %= 10;
    }
}
void cheng(int* a, int c)
{
    int jw = 0;
    for (int i = 1; i <= 1000; i++)
    {
        a[i] = a[i] * c + jw;
        jw = a[i] / 10;
        a[i] %= 10;
    }
}
int main()
{
    int n;
    cin >> n;
    a[1] = 1;
    for (int i = 1; i <= n; i++)
    {
        cheng(a, i);
        pplus(a, c);
    }
    bool flag = 0;
    for (int i = 1000; i >= 1; i--)
    {
        if (c[i] != 0) flag = 1;
        if (flag) cout << c[i];
    }
}
上一篇:对 10007 (素数)取模的理由


下一篇:入门训练 Fibonacci数列