超大数乘法程序

#include <iostream>
#include <cstring>
#include <string>
#include <cassert>
#include <cstdlib>
typedef  int  ET;
typedef  struct  NODE{
    ET     data;   
    struct NODE * p;   
    struct NODE * n;
}NODE,*NODEH;
typedef struct LIST{
    NODEH head;   
    NODEH end;   
    int   length;
}LIST,*LISTH;


inline bool InitList(LISTH& L)
{
    //将头结点L处理一下
    L=(LISTH)malloc(sizeof(LIST));   
    assert(L);   
    L->head = L->end = NULL;
    L->length=0;   
    return true;
}
inline NODEH NMalloc(const ET& elem)
{
    //返回一个新结点,其数据为elem
    NODEH temp=(NODEH)malloc(sizeof(NODE));   
    assert(temp);
    temp->data=elem;   
    return temp;
}    
inline bool PreAdd(LISTH& L,const ET& elem)
{
    //在头部加入新结点elem
    NODEH temp=NMalloc(elem);
    ++(L->length);   
    if(NULL==L->head&&NULL==L->end){
        temp->n=temp->p=NULL;       
        L->head=L->end=temp;
        return true;
    }         
    temp->p= NULL;   
    temp->n= L->head;
    L->head->p=temp;   
    L->head= temp;    
    return true;
}
inline bool EndAdd(LISTH& L,const ET& elem)
{
    //在尾部加入新结点elem
    NODEH temp=NMalloc(elem);
    ++(L->length);   
    if(NULL==L->head&&NULL==L->end){
        temp->n=temp->p=NULL;
        L->head=L->end=temp;
        return true;
    }      
    temp->n=NULL;   
    temp->p=L->end;
    L->end->n=temp;   
    L->end=temp;    
    return true;
}
inline bool DestoryList(LISTH& L)
{
    //将表L 释放
    NODEH temp=L->head,it;
    if(temp==NULL){
        free(L);
        return true;
    }   
    while(temp!=L->end){
        it=temp;
        temp=temp->n;
        free(it);
    }
    free(temp);
    free(L);  
    return true;
}    
inline void PrintList(LISTH& L)
{
    //print
    NODEH it=L->head,end=L->end; 
    if(it==NULL)return; 
    for(;it!=end;it=it->n)
        putchar(it->data+'0');
    putchar(it->data+'0');  
}
inline bool AddZero(LISTH& L,int count)
{
    //在L的尾部加上count个0
    while(count--)EndAdd(L,0);
    return true;

inline bool BitMul(LISTH& L,const int number,LISTH& NUM)
{
    //将L与数number相乘 后的结果存入NUM中去
    //NUM应当为空表结构!!!!!!!!!
    NODEH L_end=L->end;
    int status=0,temp;
    for(; L_end!=L->head ;L_end=L_end->p){
        temp= L_end->data * number + status;
        PreAdd(NUM, temp%10 );
        status= temp/10;               
    }
    temp= L->head->data * number + status;
    if(temp>10){
        PreAdd(NUM,temp%10 );
        PreAdd(NUM,temp/10);
    }
    else PreAdd(NUM,temp);       
    //少一次哦:)   
    return true;

inline bool ADD(const LISTH& La,LISTH& Lb)
{
    // Lb= La+Lb
    NODEH pa=La->end,pb=Lb->end;
    int status=0;
    for(;pa!= La->head;pa=pa->p,pb=pb->p){
        if(pb==NULL){
            PreAdd(Lb,0);
            pb=Lb->head;
        }
        int sum=pa->data+pb->data+status;
        if(sum>=10){
            pb->data=sum%10;
            status=1;
        }
        else{
            pb->data=sum;
            status=0;
        }                               
    }
    if(pb==NULL){
        PreAdd(Lb,0);
        pb=Lb->head;
    }
 int sum= pa->data + pb->data +status;
    if( sum>=10){
        pb->data=sum%10;
        if(pb->p ==NULL){
            PreAdd(Lb,0);
            pb=Lb->head;
            pb->data=sum/10;
            return true;
        }
        pb=pb->p;
  if(pb==NULL){
   PreAdd(Lb,0);
   pb=Lb->head;
  }
        pb->data=sum/10;
  return true;
    }
 else  //sum<10
    pb->data=sum;
    return true;       
}                   
///
inline void MUL(const char * a,const char *b)
{
    //init
    LISTH CS=NULL;  //乘数
    LISTH BCS=NULL; //被乘数
    LISTH NUM=NULL; //结果
    assert(a&&b);
    assert(InitList(NUM));
    assert(InitList(CS)&&InitList(BCS));
    {
        //符号处理
        int sig=1;
        if('-'==*a){
            ++a;          
            sig*=-1;
        }
        else if('+'==*a) ++a;
        if('-'==*b){
            ++b;
            sig*=-1;
        }
        else if('+'==*b)++b;       
        if(sig<0)putchar('-');
    }        
    if(strcmp(a,b)>0){
        const char *pa= a,*pb=b;
        for(;'/0'!=*pa;++pa){
            int temp= *pa-'0';
            assert(EndAdd(BCS,temp) );
        }
        for(;'/0'!=*pb;++pb){
            int temp= *pb-'0';
            assert(EndAdd(CS,temp) );
        }
    }
    else {
        const char *pa= a,*pb=b;
        for(;'/0'!=*pa;++pa){
            int temp= *pa-'0';
            assert(EndAdd(CS,temp) );
        }
        for(;'/0'!=*pb;++pb){
            int temp= *pb-'0';
            assert(EndAdd(BCS,temp) );
        }
    }           
    //  init end!!!!
    NODEH cs_p= CS->end;
    int   bit = 0;//位数
    for(; cs_p !=CS->head ; cs_p=cs_p->p){
        LISTH TEMP;
        InitList(TEMP);       
        BitMul(BCS,cs_p->data,TEMP);
        ///
        puts("===============================================================/n");
        PrintList(BCS);///
        printf(" X %d=",cs_p->data);
        PrintList(TEMP);       
        ///
        //<==============================  here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        AddZero(TEMP,bit);
        ADD(TEMP,NUM);
  /
     puts("/nNUM:");
  PrintList(NUM);
  printf("/nbit:%d/n",bit);
  
        ++bit;
        DestoryList(TEMP);
    }   
    LISTH TEMP;
    InitList(TEMP);
    BitMul(BCS,cs_p->data,TEMP);
 ///
        puts("===============================================================/n");
        PrintList(BCS);///
        printf(" X %d=",cs_p->data);
        PrintList(TEMP);       
        ///
        //<==============================  here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    AddZero(TEMP,bit);
    ADD(TEMP,NUM); 
 /
     puts("/nNUM:");
  PrintList(NUM);
  printf("/nbit:%d/n",bit);
  
    ///    
    std::cout<<'/n'<<"结果=";
    PrintList(NUM);
    putchar('/n');
    ///清理工作
    DestoryList(TEMP);
    DestoryList(BCS);
    DestoryList(CS);
    DestoryList(NUM);   
}                                  
int main(void)
{   
    std::string a,b;
    std::cin>>a;
    std::cin>>b;
    MUL(a.c_str(),b.c_str());
   
    system("pause");
    return 0;
}   
大位数计算程序清单 1. 第一个操作数文件 A1.txt 2. 第二个操作数文件 A2.txt 3. VC6老版本程序 bc.exe 4. VC2015新版本程序 BigCom.exe 5. 新版乘法批处理 cheng.bat 6. 新版除法批处理 chu.bat 7. 新版加法批处理 jia.bat 8. 新版减法批处理 jian.bat 9. 随机测试文件生成 CreateTestFiles.py 10随机测试文件生成图形版 DataCreater.exe 说明: 1. 测试数据的构造 可以使用清单中10的软件在图形化条件下构建测试文件,但是数据是固定1位或者几位的简单重复;如果需要随机的测试数据,可以使用清单9中的python脚本。使用前可以到www.python.org下载python 2.7安装一下就可以在命令行运行,然后就能自动生成指定长度的测试文件A1和A2了。 2.测试的验证 由于数据量比较大,可以分别使用程序清单4的软件和其他5~8批处理计算结果比较,用于验证计算的结果是否一致。其中清单中5~8的批处理是调用最新版2015实现;要使用清单3老版本的程序,可以按照5~8构建对应测试批处理或者直接在命令行指定参数,例如进行乘法可以使用命令 bc m。需要注意, 测试的时候C1.txt会被覆盖,需要先重命名上一次的文件。 3.关于最大计算位数当前设定的是不过2147483648位,即计算的结果也不能过这个位数。 4.本次新版发布是支持Win7 x64以及以后的平台,如果需要,可以编译为Linux或者MacOS平台上进行运算。 5.文件中C1.txt是使用新版程序结算乘法的结果,C2.txt是用旧版计算的结果,可以对比一下结果一致。但使用时间相差了几十秒!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值