大整数的加减乘除

多项式的加减乘除能够利用多项式的加减乘除进行运算,所以下面程序採用了多项式的加减乘除。多项式运算已经在《算法导论》第30章有简要的介绍,详细的请參考数学书。

大整数加法:(利用书上公式轻松得出)

//多项式加法-大数加法
#include <iostream>
#include <time.h>
using namespace std;
#define m1 4
#define m2 5
//a[0]=x^0 a[1]=x^1....a[n]=x^n的关于x的多项式系数
//b[0]=x^0 b[1]=x^1....b[n]=x^n表示还有一关于x的多项式系数
//多项式的系数也能够看做每位上的数字
const int k=m1<m2?m2:m1;
void Simple_Large_int_add(int a[],int b[],int c[])
{
for (int i=0;i<=k;i++)
{
c[i]+=a[i]+b[i];
if (c[i]>=10)
{
c[i+1]=c[i]/10;
c[i]%=10;
}
}
}
void main()
{
srand( (unsigned)time( NULL ) );
int a[k+1]={4,2,5,1,7};//12345X12345=152399025
int b[k+1]={6,2,1,4,0,0};
int c[k+1]={0};
for (int i=m1;i>=0;i--)
{
//a[i]=rand()%10;
cout<<a[i];
}
cout<<" + ";
for ( i=m2;i>=0;i--)
{
//b[i]=rand()%10;
cout<<b[i];
}
cout<<"=";
Simple_Large_int_add(a,b,c);
for ( i=k;i>=0;i--)
{
if (i==k&&c[i]==0)
{
continue;
}
cout<<c[i];
}
cout<<endl;
}

大整数减法:(和加法类似)

//多项式减法-大数减法
#include <iostream>
#include <time.h>
using namespace std;
#define m1 1000
#define m2 898
//a[0]=x^0 a[1]=x^1....a[n]=x^n的关于x的多项式系数
//b[0]=x^0 b[1]=x^1....b[n]=x^n表示还有一关于x的多项式系数
//多项式的系数也能够看做每位上的数字
const int k=m1<m2?m2:m1;
void Simple_Large_int_Sub(int a[],int b[],int c[])
{
for (int i=0;i<=k;i++)
{
if (k==m1)
{
if (a[i]<b[i])
{
c[i]+=a[i]+10-b[i];
a[i+1]=a[i+1]-1;
}
else c[i]+=a[i]-b[i];
}
else
{
if (b[i]<a[i])
{
c[i]+=b[i]+10-a[i];
b[i+1]=b[i+1]-1;
}
else c[i]+=b[i]-a[i];
}
}
}
void main()
{
srand( (unsigned)time( NULL ) );
int a[k+1]={0};//12345X12345=152399025
int b[k+1]={0};
int c[k+1]={0};
for (int i=m1;i>=0;i--)
{
a[i]=rand()%10;
cout<<a[i];
}
cout<<" - ";
for ( i=m2;i>=0;i--)
{
b[i]=rand()%10;
cout<<b[i];
}
cout<<" = ";
Simple_Large_int_Sub(a,b,c);
int temp=k;
if (k==m2)
{
temp=k;
c[temp]=-c[temp];
while (c[temp]==0)
{
--temp;
c[temp]=-c[temp];
if (c[temp]!=0)
{
break;
}
}
}
for ( i=temp;i>=0;i--)
{
cout<<c[i];
}
cout<<endl;
}

大整数的乘法:(利用书上的公式轻松得出)

//多项式乘法-大数乘法
#include <iostream>
#include <time.h>
using namespace std;
#define m1 300
#define m2 400
#define n m1+m2
//a[0]=x^0 a[1]=x^1....a[n]=x^n的关于x的多项式系数
//b[0]=x^0 b[1]=x^1....b[n]=x^n表示还有一关于x的多项式系数
//多项式的系数也能够看做每位上的数字
void Simple_Large_int_multiplication(int a[],int b[],int c[])
{
for (int j=n-1;j>=0;j--)
{
int i=n-1-j;
for (int k=0;k<=j;k++)
{
c[i]+=a[k]*b[j-k];
}
if (c[i]>=10)
{
c[i+1]=c[i]/10;
c[i]%=10;
}
}
}
void main()
{
srand( (unsigned)time( NULL ) );
int a[n+1]={0};//12345X12345=152399025
int b[n+1]={0};
int c[n+1]={0};
for (int i=0;i<m1;i++)
{
a[i]=rand()%10;
cout<<a[i];
}
cout<<" X ";
for ( i=0;i<m2;i++)
{
b[i]=rand()%10;
cout<<b[i];
}
cout<<" = ";
Simple_Large_int_multiplication(a,b,c);
for ( i=n;i>0;i--)
{
if (i==n&&c[i]==0)
{
continue;
}
cout<<c[i];
}
cout<<endl;
}

大整数的除法:(能够由大整数减法得出,算是比較复杂的一个四则运算了)

參考资料:超大整数除法 
可是这个链接里的代码有3点须要说明:1,当被除数与除数同样时,会产生错误,比方701/101返回的是1,而不是6.  
2,这个代码用了string数组,我和他不太一样,我用的是int数组,所以代码还是有差别的。3,另一点须要说明,他的代码用了
itoa系统函数,这个函数在VS2013编译器已经被废弃了。

//*************************超长整数除法*******************************/
//*核心思想是程序中使用了int数组存放大整数的每一位,扩大除数的倍数使其*/
//*位数与被除数位数同样,然后被除数与除数每循环一次,就比較一次。*****/
//*假设被除数<除数,不进行大整数的减法,除数降低1位继续下一次循环****/
//*假设被除数>除数,进入大整数的循环减法操作直到被除数小于除数,*****/
//*而后相同进行下一层循环。这样经过数次循环直到被扩大倍数的除数位*****/
//*数降低到初始除数位数为止这样能够同一时候得到余数和商完毕大整数除法操作*/
//*比如10480÷45扩大100倍=>10480÷45000降低1位=>10480÷4500发现能减2次/
//*1048÷4500缩小1位=>1048÷450发现能减3次=>130÷450降低1位=>130÷45**/
//*发现能减2次=>40÷45除数为初始除数循环结束,除法结束 终于余数40商232/
//*这除法执行时间是对于β位的大整数须要O(β^2)时间********************/
#include <iostream>
#include <time.h>
using namespace std;
#define m1 500
#define m2 150
//a[0]=x^0 a[1]=x^1....a[n]=x^n的关于x的多项式系数
//b[0]=x^0 b[1]=x^1....b[n]=x^n表示还有一关于x的多项式系数
//多项式的系数也能够看做每位上的数字
const int k = m1<m2 ? m2 : m1;
int len1 = m1, len2 = m2;
//被除数大于除数的辅助大整数减法函数
void help1(int a[], int b[], int c[])//O(β) 对于β位整数来说
{
 int j = k;
 while (j >= 0)c[j--] = 0;
 for (int i = 0; i <= k; i++)
 {
  if (a[i]<b[i])
  {
   c[i] += a[i] + 10 - b[i];
   a[i + 1] = a[i + 1] - 1;
  }
  else c[i] += a[i] - b[i];
  a[i] = c[i];
 }
 while (!a[len1]) --len1;
}
//大整数的减法
int Simple_Large_int_Sub(int a[], int b[], int c[])//O(β) 对于β位整数来说
{
 if (len1 == len2)
 {
  int i = len1;
  while (a[i] == b[i]) i--;
  if (a[i]>b[i])
  {
   help1(a, b, c);
   return 1;
  }
  else return -1;
 }
 else
 {
  if (len2<len1)
  {
   help1(a, b, c);
   return 1;
  }
  else return -1;
 }
}
int divide(int a[], int b[], int c[])
{
 int res[k + 1] = { 0 }, temp = 0, flag = 0;//res数组是存放商的数组
 if (len2 == 0 && b[0] == 0)
 {
  cout << "除数不能为0!" << endl;
  return 0;
 }
 if (len1<len2)
 {
  return 1;
 }
 else
 {
  if (len1 == len2)
  {
   int i = len1;
   while (a[i] == b[i])i--;
   if (a[i] < b[i])return 1;
  }
  while (!b[len2])len2--;//00xxx...化简为xxx,第一个非0数字之前的所有0所有去掉后计算大整数的实际位数
  while (!a[len1])len1--;//同上,假设不进行随机生成大整数的话,那么这两个循环能够省略掉
  int p = len1 - len2;
  int j = len2, q = len2;
  int i = (len2 += p);
  while (i >= 0)//这个循环是给除数末尾补0使其与被除数位数一样,
  {
   if (j<0)
   {
    b[i--] = 0;
    continue;
   }
   b[i] = b[j];
   --i; --j;
  }
  while (p >= 0)//O(cβ^2)
  {//O(β1-β2)=O(β)最外层循环运行次数就是2个整数的差值,最大可能到β位(由于β位-1位=β位)
   int t = 0;
   int  q2 = len2;//q2至少为1
   while (Simple_Large_int_Sub(a, b, c) >= 0)//O(cβ)每次计算大整数相减,都要进行β次循环
    t++;//t<10=>O(c) 最多循环9次,所以这层循环仅仅需花费常数时间
   res[p] = t;
   if (res[p] != 0 && flag == 0){
    temp = p;
    flag = 1;
   }
   p--; //len2--;
   int i = 0;
   q2 -= len1;//计算len2降低的实际位数
   if (q2 == 0)q2 = 1;
   len2 -= q2;
   while (i <= k&&len2>q - 1)
   {
    if (i>len2)
    {
     b[i++] = 0;
     continue;
    }
    b[i] = b[i + q2];
    i++;
   }
   if (len2 <= q - 1){ break; }//假设经过X10加倍的除数降低到小于等于原来的除数-1,那么除法结束跳出循环 
   while (q2>1)//假设q2降低的位数超过1位,那么须要给商补0
   {
    res[p--] = 0;
    q2--;
   }
  }
  cout << "商=";
  for (j = temp; j >= 0; j--)
  {
   cout << res[j];
  }
  return 2;
 }//除数长度大于被除数长度
}
void main()
{
 srand((unsigned)time(NULL));
 int a[k + 1] = { 0 };
 int b[k + 1] = { 0 };
 int c[k + 1] = { 0 };//c为暂时数组
 for (int i = m1; i >= 0; i--)
 {
  a[i]=rand()%10;
  cout << a[i];
 }
 cout << " ÷ ";
 for ( i = m2; i >= 0; i--)
 {
  b[i] = rand() % 10;
  cout << b[i];
 }
 cout << " = ";
 int p = divide(a, b, c);
 if (p == 1)
 {
  cout << "商=" << "0" << endl;
  cout << "余数=";
  for (int i = m1; i >= 0; i--)
  {
   cout << a[i];
  }
 }
 else if (p == 2)
 {
  cout << "余数=";
  int i = k;
  while (!a[i]&&i!=0)--i;
  for (int j = i; j >= 0; j--)
  {
   cout << a[j];
  }
 }
 else cout << "输入错误!" << endl;
 cout << endl;
}

??

大整数的加减乘除,布布扣,bubuko.com

时间: 2024-12-14 18:40:48

大整数的加减乘除的相关文章

关于大整数的加减乘除求余运算 java

自己用java 实现了大字符串整数的加减乘除和求余运算, 加减法的算法是模拟手工笔算的计算过程, 除法就是从最高位不停的减操作, 乘法的算法 :遍历一个数的各个位数以及他所在位置,另一个数根据这个数的位置末位添n个0,然后累加次数为这个位置数的数值 原创代码如下: public class Demo6 { public static void main(String[]args){ System.out.println(add("-989","989")); Sys

大整数的加减乘除C++实现

大整数的乘法由于用分治法理解起来有点困难,就采用人的计算方法实现,大整数为string 类型,结果也为string类型. 大整数的除法采用先乘后减的方法,例如: 665/20 首先20*10=200:然后665去减200,通过循环计入减了3次,则结果记入3*10=30:然后20*1=20,上次减了之后还剩65,65-20,又减了3次,所以结果记入30+3*1=33:最后还剩5,比20小,则余数为5. 大整数的加法减法和人工打草稿过程类似,不做详细分析.实现代码仅供参考: 1 #include<i

N!的阶乘附带简单大整数类的输入输出(暂时没有深入的了解)

Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N! 我的思路:就想着大整数类去了,才发现自己还不能很好的掌握,其实这是一个大整数与int的乘法,一个50000的数组完全可以解决,看来分析问题的能力还是比较弱呀,希望能够提升分析问题的全局能力! #include<iostream>#include<cstdio>#include<string>#include<cstring>#inc

大整数运算C++1

//下面的代码勉强算是bignum_beta1版本! //实现了大整数的加减乘除四则运算,以及求两个整数的最大公约数,以及求乘法逆,miller_rabin素性检验,平方_乘法算法 //不足之处,位数还很难扩展至几千位,以及运算速度有一点慢,既然是beta1,说明bug还是挺多的 //程序缺少测试数据来测试,所以有的结果不敢保证其正确性 //由于使用c++复写了很多运算符,加入这个文件之后,大数bignum可以看做是一个如同如同int一样的基本类型 //可以像int一样加减乘除和输入输出 #in

大整数运算C++

//下面的代码勉强算是bignum_beta1版本! //实现了大整数的加减乘除四则运算,以及求两个整数的最大公约数,以及求乘法逆,miller_rabin素性检验,平方_乘法算法 //不足之处,位数还很难扩展至几千位,以及运算速度有一点慢,既然是beta1,说明bug还是挺多的 //程序缺少测试数据来测试,所以有的结果不敢保证其正确性 //由于使用c++复写了很多运算符,加入这个文件之后,大数bignum可以看做是一个如同如同int一样的基本类型 //可以像int一样加减乘除和输入输出 #in

Java 实现大整数加减乘除

自己用Java实现的大整数加减乘除运算.还有可以改进的地方,有兴趣的童鞋可以加以改进.仅供参考,请勿转载! package barrytest; import java.util.ArrayList;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern; //@author Barry Wang// all the four method have not considered th

大整数的存储与加减乘除四则运算

当需要计算的整数或计算结果可能会超出long long 所能表示的范围时,应该用大整数来存储和计算(Java里面有BigInteger来存储大整数,这里讨论的是C++语言). 大整数的存储形式是下面这个结构体(包含了构造函数): // 大整数结构体 struct bign{ int d[1000]; int len; bign(){ memset(d, 0, sizeof(d)); len = 0; } }; 首先以字符串的形式读去数据,然后将字符串逐个逆序字符存入d[]数组(可以采用用reve

大整数运算

对于A,B的范围在int范围内,求解A与B的加减乘除运算我相信大家很快就可以写出程序来,但是如果A,B是有着1000个数位的整数呢?恐怕就没有已有的数据类型来表示了,这时候只能老实的模拟加减乘除运算的过程.模拟加减乘除的运算的过程,原理就是小学的. 大整数又称为高精度整数,其含义就是用基本的数据类型无法存储其精度的整数.大整数运算即高精度运算. 首先,介绍大整数的存储. 很简单,用数组即可.例如,int型数组d[1000]:如将123456存储到数组中,则有d[0]=6,d[1]=5......

大整数算法[01] 大整数的表示和相关定义

★ 相关的数据类型定义 在干正事之前,先定义好各种数据类型还是很有必要的,避免在以后的编码中引起混乱. uintX   X位无符号整形,如uint32表示32位无符号整形 intX    X位有符号整形,如int32表示32位有符号整形 基本数据类型定义: #ifdef _MSC_VER            typedef __int8              int8;            typedef __int16             int16;            typ