大数相乘 - 整型

 

搞程序的是不是都熬夜的呢?我是的,不过很快就会努力不是了.为了健康,做一个不熬夜的程序员
本来打算了5:00睡的,鬼使神差莫明其妙地放下了PHP写了点C++,于是就有了以下代码的产生,也许是太久没有写C++了.

关于算法我已经写在程序的注释里了.简言之是先相加(不管进位),最后一起进位.

//  $Id: multi.cpp 6 2006-11-01 21:12:48Z JiangMiao $ 
//  JiangMiao's Blog  http://blog.csdn.net/antter
#include  " stdafx.h "
#include 
< iostream >
#include 
< string >
using   namespace  std;


///  转换字符串为
char *  strToInt( const   string &   in
    {
    
char *  rt = new   char [ in .size()];
    
for (size_t i = 0 ;i < in .size();i ++
        {
        rt[i]
= in [i] - ' 0 ' ;
        }
    
return  rt;
    }

/* *
 * 大数相乘,最大位数 0.04G 即32位int/(9*9)
 
*/
string  mul( const   string &  sa, const   string &  sb) 
    {
    
string  rt;
    size_t la
= sa.size();
    size_t lb
= sb.size();
    size_t lr
= la + lb;  // 最大可能位数
     char *  a = strToInt(sa);
    
char *  b = strToInt(sb);
    unsigned  
int *  r = new  unsigned  int [lr]; // 分配结果空间
    size_t ia,ib,ir;
    rt.reserve(lr);
    memset(r,
0 ,lr * sizeof ( int ));
    
for (ia = 0 ;ia < la;ia ++ // 相乘
        {
        
for (ib = 0 ;ib < lb;ib ++ )
            {
            ir
= ib + ia + 1 ;
            r[ir]
+= a[ia] * b[ib];
            }
        }
    
for (ir = lr - 1 ;ir > 0 ;ir -- // 进位
        {
        
int  add = r[ir] / 10 ;
        r[ir
- 1 ] += add;
        r[ir]
%= 10 ;
        }
    
for (ir = 0 ;ir < lr;ir ++ // 除去前面多余的0
        {
        
if (r[ir] != 0 )
            
break ;
        }
    
for (;ir < lr;ir ++ // 生成字串
        {
        rt.append(
1 ,r[ir] + ' 0 ' );
        }
    delete a;
    delete b;
    delete r;
    
return  rt;
    }

/*
提升性能的改进:
1. 使用char* 代替string
2. 多数相乘返回非string,最后由intToStr进行字串输出,可极大地节省预处理和生成的时间

实现以上两点性能提升至少45%,乱猜的 :)
*/


///  以下为测试文件
#include  " windows.h "
int  main( int  argc, char **  argv)
    {
    
string  rt;
    LARGE_INTEGER fre,begin,end;
    QueryPerformanceFrequency(
& fre);
    QueryPerformanceCounter(
& begin);

    
// 10000阶乘测试
    rt = " 1 " ;
    
for ( int  i = 1 ;i <= 10000 ;i ++ )
        {
        
char  b[ 6 ];
        _itoa_s(i,b,
10 );
        rt
= mul(rt,b);
        }

    QueryPerformanceCounter(
& end);
    cout
<< " Spend  " << (end.QuadPart - begin.QuadPart) * 1000000 / fre.QuadPart << " ns " << endl;
    cout
<< rt.size() << endl;
    
// cout<<rt<<endl;
     return   0 ;
    }


/*  测试10000!的结果
 * C4 2.66MHZ
Spend 16911238ns //17s
35660.
 
*/

 

欢迎探讨.我的Blog是 http://blog.csdn.net/antter

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值