最多支持0.04G位的大浮点数相乘算法,提供10000阶乘的例子.

昨天,噢不,今日拂晓,鸡鸣之时,写了一大整型数相乘,下午有空,改进了一下,昨天直觉说实现以上几点能提升45%今天一试,哈准.果然是45%左右

2006-11-2 14:12
修改:
1. 对字符串进行封装为bignum
2. 内部由char* 代替string
3. 支持浮点运算.

性能提升50%

提升性能的改进设想:
1. 对于小型的long,int,__int64等,采用非string的处理方式,以减少整型与字串转换.

实现以上1点,性能大约提升5%~10%,乱猜的 :)

如果可能的话会加上除法

//  $Id: multi.cpp 7 2006-11-02 06:30:51Z JiangMiao $ 
//  JiangMiao's Blog  http://blog.csdn.net/antter
#include  " stdafx.h "
#include  < iostream >
#include  < string >
using   namespace  std;

#define  SAFE_DELETE(p) if((p)!=NULL){delete p;p=NULL;}
typedef unsigned  long  DWORD;
#define  OK 0
#define  FAIL (DWORD)-1

class  bignumFunc
    {
    
     public :
     ///  转换字符串为
    inline  static   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;
        }

};
class  bignum
    {

char *  str;
    size_t length;
    size_t point;

public :
    bignum():str(NULL),length( 0 ),point( 0 )
        {
        }
     ~ bignum()
        {
        }
    bignum( const  bignum &  b)
        {
        init(b.length);
        length = b.length;
        point = b.point;
        memcpy(str,b.str,length);
        }
    size_t size()
        {
         return  length;
        }
    DWORD reset()
        {        
        SAFE_DELETE(str);
        length  =   0 ;
        point  =   0 ;
         return  OK;
        }

//  分配空间
    DWORD init(size_t length)
        {
        reset();
        str = new   char [length];
        memset(str, 0 ,length);
         return  OK;
        }

//  读入string
    DWORD read( const   string &   in )
        {
         return  read( in .c_str(), in .size());
        }
    DWORD read( const   char *   in ,size_t length)
        {
        init(length);
         char *  str = this -> str;
        size_t i;
         for (i = 0 ;i < length;i ++ )
            {
            ( * str ++ ) = ( * in ++ ) - ' 0 ' ;
             if (( * in ) == ' . ' ) 
                {
                i ++ ;
                 break ;
                }
            }
        point = i;
         if (i == length) 
            {
             this -> length = i;
             return  OK;
            }
        i ++ ;            
         for (;i < length;i ++ )
            {
            ( * str ++ ) = ( *++ in ) - ' 0 ' ;
            }
         this -> length = i - 1 ;
         return  OK;
        }

// 输出到string
     string  toString()
        {
         string  rt;
        rt.reserve(length + 1 );
        size_t i;
         for (i = 0 ;i < point;i ++ )
            {
            rt.append( 1 ,str[i] + ' 0 ' );
            }
         if (length != point) 
            {
            rt.append( 1 , ' . ' );
             for (;i < length;i ++ )
                {
                 // 这里可加入小数点后的末尾0不输出
                rt.append( 1 ,str[i] + ' 0 ' );
                }
            }
         return  rt;
        }

/* *
     * 大数相乘,最大位数 0.04G 即32位int/(9*9)
      */
     static  bignum *  mul(bignum *  rt,bignum *  sa,bignum *  sb)
        {
        size_t la = sa -> length;
        size_t lb = sb -> length;
        size_t xs = sa -> point + sb -> point; // 小数位数
        size_t lr = la + lb;  // 最大可能位数
         char *  a = sa -> str;
         char *  b = sb -> str;
        unsigned   int *  r = new  unsigned  int [lr]; // 分配结果空间
        size_t ia,ib,ir;
        rt -> init(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 ;
            }
        size_t i = 0 ;
         for (ir = 0 ;ir < lr;ir ++ )  // 除去前面多余的0
            {
             if (r[ir] != 0 )
                 break ;
            i ++ ;
            }
        xs -= i;
        i = 0 ;
         char *  dr = rt -> str;
         for (;ir < lr;ir ++ )  // 生成字串
            {
            dr[i ++ ] = r[ir];
            }
         // Reserved: 除去尾部多余0,如果放入输出函数可提升效率
        rt -> length = i;
        rt -> point = xs;
        delete r;
         return  rt;
        }
    };

class  bignumBuilder
    {
     public :
         static  bignum *  build( const   string &  str)
            {
            bignum *  bn = new  bignum();
            bn -> read(str);
             return  bn;
            }
    };

/*

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

实现以上两点性能提升至少45%,乱猜的 :)
-------------------------------------------
Revision: 7
2006-11-2 14:12
修改:
1. 对字符串进行封装为bignum
2. 内部由char* 代替string
3. 支持浮点运算.

性能提升50%

提升性能的改进设想:
1. 对于小型的long,int,__int64等,采用非string的处理方式,以减少整型与字串转换.

实现以上1点,性能大约提升5%~10%,乱猜的 :)
-------------------------------------------
*/

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

/*     10000阶乘测试
    cn->read("1");
    for(int i=1;i<=10000;i++)
        {
        bignum* tmp=an;
        an=cn;
        cn=tmp;
        char b[6];
        _itoa_s(i,b,10);
        bn->read(b);
        bignum::mul(cn,an,bn);
        }
*/
    
/*
    浮点数相乘
*/
    an -> read( " 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989 " );
    bignum::mul(cn,an,an);

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

/*  测试10000!的结果
 * C4 2.66MHZ

revision: 6
Spend 16911238ns //17s
35660.

------------------------
revision: 7
10000阶乘
Spend 8441291ns (8.5秒)提升50%
35660

//1000位大浮点数相乘
Spend 3147ns
2001
请按任意键继续. . .
  */

欢迎探讨.

我的Blog是 http://blog.csdn.net/antter
Email: jmiwork@yahoo.com

大数相乘 - 浮点数相关推荐

  1. 大数相乘(数组表示)

    大数相乘 首先说一下乘法计算的算法:同样是模拟人工计算时的方法. 从低位向高位乘,在竖式计算中,我们是将乘数第一位与被乘数的每一位相乘,记录结果之后,用第二位相乘,记录结果并且左移一位,以此类推,直到 ...

  2. 大数相乘、大数相加、大数相减Java版本

    为什么80%的码农都做不了架构师?>>>    题目:两个非常大的数字相乘(相加,相减) 该题目在java中可以使用BigInteger类中的方法来实现.否则的话可以使用如下方式来实 ...

  3. 大数相乘--极简单的思路

    大数相乘,面试常见的题型,如何计算两个打算相乘? <pre style="font-family: 'Lucida Sans Typewriter'; font-size: 12pt; ...

  4. C#中关于处理两个大数相乘的问题

    方法一:直接利用.NET FrameWork 4.0中自带的System.Numeric类库 添加了对此类库的引用后,直接调用方法即可计算: View Code 1 BigInteger num1 = ...

  5. 大数相乘(c语言/c++)

    大数相乘(c语言/c++) 方法一:做加法 方法二.做乘法 方法一:做加法 思路:模拟竖乘过程.将num2从后往前一个一个的去乘num1.然后累加.在累加的时候记得在末尾补0.补的0的个数就是第二个字 ...

  6. 算法题-大数相乘问题

    今天在网上看到一个大数相乘的问题,题目是这样的:输入两个整数,要求输出这两个数的乘积.输入的数字可能超过计算机内整形数据的存储范围. 分析: 由于数字无法用一个整形变量存储,很自然的想到用字符串来表示 ...

  7. POJ 2389 Bull Math(水~Java -大数相乘)

    题目链接:http://poj.org/problem?id=2389 题目大意: 大数相乘. 解题思路: java BigInteger类解决 o.0 AC Code: 1 import java. ...

  8. 面试官让你用C语言实现大数相乘,慌吗?

    在之前的笔试题解析里面,我写了大数相加的问题,这里再剖析一个大数相乘,顾名思义,大数相乘就是这个数已经大到最大的数据类型都没有办法保存了. 我们看看最大的数据类型可以保存多大的数据. #include ...

  9. C# 使用同余代换简化多个大数相乘取模运算

    •(A + B) mod M = ( A mod M + B mod M ) mod M •(A * B) mod M = ((A mod M) *( B mod M)) mod M using Sy ...

最新文章

  1. 我是一个SDN控制器
  2. 《汇编语言》实验五课程
  3. windows 命令行
  4. 制作mac系统安装U盘
  5. eBay:PayPal今年移动支付总额将超35亿美元
  6. java 商品评价计算算法
  7. 信息化之路------广州行
  8. 南邮linux期末考试试题,南邮操作系统试卷及答案.doc
  9. (三)使用预定义模型QDirModel的例子
  10. 累累白骨下,共享单车的困局
  11. 学习gSOAP从这个网址开始
  12. 01-HTML基础与进阶-day3-录像236
  13. 文档类型字符集即HTML标签的语义化
  14. 信息爆炸,物质丰富,你不得不知的奥卡姆剃刀原则
  15. 文曲星猜数字游戏java代码_急求一份完整的文曲星上的猜数字游戏的课程设计...
  16. DS图—图的最短路径(不含代码框架)
  17. fortran 和 java_JNA实现Java调用Fortran
  18. GDPR is coming!
  19. 记一次小米2S的刷机过程
  20. 神经网络入门书籍推荐,神经网络基础书籍

热门文章

  1. Codeforces 115B Lawnmower
  2. Redis incr解决并发问题
  3. 黑苹果 wifi android,黑苹果目前已可以完美驱动内置intel WiFi
  4. php英文月份,月份英文、月份英文的縮寫│English Learning線上免費英文學習網、線上英文...
  5. 国产步进电机驱动芯片TMI8420,可pin to pin​替代DRV8825
  6. Collections。API
  7. 升级pip出现拒绝访问
  8. 从键盘输入一个字符串并输出
  9. 博客摘录「 2022年C语言程序设计题库习集带答案(史上最全版)」2023年5月2日
  10. 微软软件开发技术二十年回顾-COM、OLE、ActiveX及COM+篇