您的位置:首页 > 其它

大数相乘的一种思路(2012年软件设计大赛的启思)

2012-04-10 22:55 330 查看
      做过不少ACM试题都涉及到大数(超过32位int)的运算,有加法、阶乘的之类的。2012年的软件大赛上见到一种独特的思路,故而记之如下:

大数乘法

     
对于 32 位字长的机器,大约超过 20 亿,用 int 类型就无法表示了,我们可以选择 int64 类型,但无论怎样扩展,固定的整数类型总是有表达的极限!如果对超级大整数进行精确运算呢?

     一个简单的办法是: 仅仅使用现有类型,但是把大整数的运算化解为若干小整数的运算,即所谓:“分块法” 。如下图原理:

    表示了分块乘法的原理。可以把大数分成多段(此处为 2 段)小数,然后用小数的多次运算组合表示一个大数。可以根据 int 的承载能力规定小块的大小,比如 要把 int 分成 2 段,则小块可取 10000 为上限值。注意,小块在进行纵向累加后,需要进行 进位校正。 以下代码示意了分块乘法的原理(乘数、被乘数都分为 2 段) 。

 



        具体实现代码如下:

      参考原理图还是很容易理解的

void bigmul(int x,
int y, int r[]) 

{

  int base =
10000; 

  int x2 = x / base; 

  int x1 = x % base; 

  int y2 = y / base; 

  int y1 = y % base; 

 

  int n1 = x1 * y1; 

  int n2 = x1 * y2; 

  int n3 = x2 * y1; 

  int n4 = x2 * y2; 

 

  r[3] = n1 % base; 

  r[2] = n1 /
base + n2 % base + n3 %
base; 

  r[1] = n2 / base + n3 / base + n4 % base;// 填空,参考原理图很容易理解的
  r[0] = n4 /
base; 

 

  r[1] += r[2] / base;// 填空
  r[2] = r[2] %
base; 

  r[0] += r[1] /
base; 

  r[1] = r[1] %
base; 

}

 
int main(int argc,
char* argv[]) 

{
  int x[] = {0,0,0,0}; 

  bigmul(87654321,
12345678, x); 

  printf("%d%d%d%d\n", x[0],x[1],x[2],x[3]);  

  return 0; 

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  n2 扩展