高精度

高精度

运算:加法、减法、阶乘、乘法

翻转:

这些运算都是从小位开始,所以一般需要翻转。以字符串储存:reverse(a.begin(),a,end())。以数组储存:

 for (int i1 = lena1 - 1; i1 >= 0; i1--) {
  a1[lena1-1-i1] = a[i1] - '0';
  }
进位、借位:

加法、减法:

 for(int k=0;k<ll+1;k++){//进位运算 
  if(ans[k]>'9'){
  ans[k]-=10;
  ans[k+1]++;
  }
  }
         for(int k=0;k<ll;k++){//借位运算 
  if(ans[k]<'0'){
  ans[k]+=10;
 // cout<<ans[k];
  ans[k+1]--;
  }
  }

乘法:

 if(a[i]>=10)
                {
                     a[i+1]+=a[i]/10;
                     a[i]%=10;
                }
                 a[i]*=N;

具体题目:

P1120 大整数加法

题目描述

给出两个 200 位以内的正整数,求其和。

输入描述

多组测试数据。每组测试数据包括两行,每行一个数。

输出描述

每组测试输出一行,为所求两个整数之和。

样例输入

123

456

样例输出

579

 #include<iostream>
 #include<string>
 #include<algorithm>
 using namespace std;
 
 int main(){
  string a,b;
  while(cin>>a>>b){
  string ans;
  int aa = a.length();//字符串a长度
  int bb = b.length();//字符串b长度
  int ss = min(aa,bb);//最小长度
  int ll = max(aa,bb);//最大长度
  reverse(a.begin(), a.end());//将字符串翻转用于从小位开始计算
  reverse(b.begin(), b.end());
 
  for(int i=0;i<ss;i++)
  ans+= a[i]+b[i]-'0';//相同位数之间计算
  if(aa>bb)//将大位数单独加在字符串尾部
  {
  for(int j=ss;j<aa;j++)
  ans+= a[j];}//将
  else if(bb>aa)
  for (int j=ss;j<bb;j++)
  ans+= b[j];
  ans+='0';//用于最大位进位
  for(int k=0;k<ll+1;k++){//进位运算
  if(ans[k]>'9'){
  ans[k]-=10;
  ans[k+1]++;
  }
  }
  reverse(ans.begin(),ans.end());//翻转为正常顺序
  for(int i=ans.find_first_not_of('0');i<ll+1;i++){//找到第一位不为0的位置,一次输出
  if(i==-1){
  cout<<0;
  return 0;
  }
  cout<<ans[i]-48;
  }
  cout<<endl;
  }
  return 0;
 
 }
P1121 大整数减法

题目描述

给出两个 200 位以内的正数,算出第一个数减第二个数的值(结果为正)。

输入描述

每组测试数据包括两行,第一行为被减数,第二行为减数。

输出描述

每组测试数据输出一行,为所求两个整数之差。

样例输入

987

654

样例输出

333

 #include<iostream>
 #include<string>
 #include<algorithm>
 using namespace std;
 
 int main(){
  string a,b,temp;
  int flag = 0;
  while(cin>>a){
  cin>>b;
  string ans;
  int aa = a.length();//字符串a长度
  int bb = b.length();//字符串b长度
  int ss = min(aa,bb);//最小长度
  int ll = max(aa,bb);//最大长度
  reverse(a.begin(), a.end());//将字符串翻转用于从小位开始计算
  reverse(b.begin(), b.end());
  if(aa==bb){
  if(b>a){
  temp = a;
  a = b;
  b = temp;
  flag = 1;
  }
  }
  else if(bb>aa){
  temp = a;
  a = b;
  b = temp;
  aa = bb;
  flag = 1;
  }
  for(int i=0;i<ss;i++)
  ans+= a[i]-b[i]+'0';//相同位数之间计算
  for(int j=ss;j<ll;j++)
  ans+= a[j];
  for(int k=0;k<ll;k++){//借位运算
  if(ans[k]<'0'){
  ans[k]+=10;
 // cout<<ans[k];
  ans[k+1]--;
  }
  }
  reverse(ans.begin(),ans.end());//翻转为正常顺序
  if(flag) cout<<'-';
  for(int i=ans.find_first_not_of('0');i<ll;i++){//找到第一位不为0的位置,一次输出
 
  cout<<ans[i]-48;
  }
  cout<<endl;
  }
  return 0;
 
 }
P1134 高精度阶乘

题目描述

求一个非负整数 N 的阶乘的精确值(N 的大小保证 N 的阶乘不超过 3000 位)。

输入描述

有多组测试数据,每组测试数据包含一行非负整数 N。

输出描述

对于每组测试数据,输出一行答案。

样例输入

3

10

50

样例输出

6

3628800

30414093201713378043612608166064768844377641568960512000000000000

 #include<bits/stdc++.h>
 using namespace std;
 //对每一位进行数字乘法,处理好进位
 int main()
 {
     int N;
     while(cin>>N)
    {
         int a[3001]={0};
         int i=0;
         a[0]=1;
         while(N)
        {
             for(i=0;i<3001;i++)
            {
                 if(a[i]>=10)
                {
                     a[i+1]+=a[i]/10;
                     a[i]%=10;
                }
                 a[i]*=N;
            }
             N--;
        }
         while(a[i]==0)
        {
             i--;
        }
         for(;i>=0;i--)
             cout<<a[i];
         cout<<endl;
    }
     return 0;
 }
P1136 高精度乘法

题目描述

给出两个长度小于 100 位的正整数,求其乘积。

输入描述

两行,一行一个数。

输出描述

一行,为所求乘积。

样例输入

1937

2931

样例输出

5677347

 #include<iostream> 
 #include<cstring>
 using namespace std;
 //将字符串每一位改为数字,再反向计算,最后处理进位问题。
 int main() {
  char a[101], b[101];       //定义字符数组是为了好测量,输入的长度
  while (cin >> a >> b) {
  char swap[101];         //用来进行交换的,超过a的长度小于b的长度
  int a1[101] = { 0 }, b1[101] = { 0 };  //接受a与b的,并将其转化为整形数组和反转
  int lena1, lenb1;      //测量a与b的长度
  lena1 = strlen(a), lenb1 = strlen(b);
  int n;                 //接受lena1与lena2的最大值,并且为下面的动态数组做准备
  n = (lena1 > lenb1 ? lena1 : lenb1);
  //申请动态数组,a与b的乘积最多有2*n位数
  int *p;
  p = new int[2 * n];
  //将p数组清零
  memset(p, 0, sizeof(int)*(2 * n));
  //控制b1为最短的数组
  if (lena1 < lenb1) {
  strcpy(swap, b);
  strcpy(b, a);
  strcpy(a, swap);
  }
  lena1 = strlen(a), lenb1 = strlen(b);
  //反转a数组
  for (int i1 = lena1 - 1; i1 >= 0; i1--) {
  a1[lena1-1-i1] = a[i1] - '0';
  }
  //反转数组b
  for (int k1 = lenb1 - 1; k1 >= 0; k1--) {
  b1[lenb1 - 1 - k1] = b[k1] - '0';
  }
  int len;    //控制p数组从第几位开始
  for (int i = 0; i < lenb1; i++) {
  len = i;
  for (int k = 0; k < lena1; k++) {
  p[len] += b1[i] * a1[k];
  if (p[len] > 9) {
  p[len + 1] += p[len] / 10;
  p[len] = p[len] % 10;
  }
  len++;
  }
  }
  while (p[len] == 0) {
  len--;
  }
  for (int k2 = len ; k2 >= 0; k2--) {
  cout << p[k2];
  }
  delete[]p;
  cout << endl;
  }
  return 0;
 }
 
posted @ 2022-05-18 16:42  chanxe  阅读(149)  评论(0编辑  收藏  举报