大整数运算

 用分治算法思想实现的大整数乘法

http://blogger.org.cn/blog/more.asp?name=njucs&id=10146

上大学算法分析实验课的内容.关于利用分治法大整数乘法.还没有解决大整数的存储方式,应该是要利用一维数组来解决.所以目前只是5位数的运算没有问题.程序不是很健全,但是算法的核心部分应该是已经都在这里了.

VC++6.0下测试通过.

#include <iostream.h>
#include <math.h>

long mult(long x,long y,int n);
int num(long x);

void main() //主函数
{
 long x,y;
 cout<<"input x and y:"<<endl;
 cin>>x>>y;
 cout<<mult(x,y,num(x))<<endl;
}

long mult(long x,long y,int n)
{
 long a,b,c,d,s;
 if (n=1)
  return x*y;
 else
 {
  a=long(x/pow(10,(n/2))); //取x的左半部分
  b=long(x%long(pow(10,(n/2)))); //取x的右半部分
  c=long(y/pow(10,(n/2))); //取y的左半部分
  d=long(y%long(pow(10,(n/2)))); //取y的右半部分
  s=mult(a,c,n)*pow(2,n)+(mult((a-b),(d-c),n)+mult(a,c,n)+mult(b,d,n))*pow(2,n/2)+mult(b,d,n); //书上的公式
  return (s);
 }
}

int num(long x) //判断输入的数字的位数
{
 int i=0;
 if(x-9<=0)
  return 1;
 else
 {
  while (x!=0)
  {
   i++;
   x=x/10;
  }
  return i;
 }
}

 

第二种思路:

Algorithm Gossip: 超长整数运算(大数运算)

说明

基于记忆体的有效运用,程式语言中规定了各种不同的资料型态,也因此变数所可以表达的最大整数受到限制,例如123456789123456789这样的整数就不可能储存在long变数中(例如C/C++等),我们称这为long数,这边翻为超长整数(避免与资料型态的长整数翻译混淆),或俗称大数运算。

解法

一个变数无法表示超长整数,则就使用多个变数,当然这使用阵列最为方便,假设程式语言的最大资料型态可以储存至65535的数好了,为了计算方便及符合使用十进位制的习惯,让每一个阵列元素可以储存四个位数,也就是0到9999的数,例如:
大数运算

很多人问到如何计算像50!这样的问题,解法就是使用程式中的乘法函式,至于要算到多大,就看需求了。

如果您使用的是Java,那么在java.lang下有BigInteger与BigDecimal可以直接进行大数运算。

由于使用阵列来储存数值,关于数值在运算时的加减乘除等各种运算、位数的进位或借位就必须自行定义,加、减、乘都是由低位数开始运算,而除法则是由高位数开始运算,这边直接提供加减乘除运算的函式供作参考,以下的N为阵列长度。


实作

  • C
void add(int *a, int *b, int *c) { 
int i, carry = 0;

for(i = N - 1; i >= 0; i--) {
c[i] = a[i] + b[i] + carry;
if(c[i] < 10000)
carry = 0;
else { // 进位
c[i] = c[i] - 10000;
carry = 1;
}
}
}

void sub(int *a, int *b, int *c) {
int i, borrow = 0;

for(i = N - 1; i >= 0; i--) {
c[i] = a[i] - b[i] - borrow;
if(c[i] >= 0)
borrow = 0;
else { // 借位
c[i] = c[i] + 10000;
borrow = 1;
}
}
}

void mul(int *a, int b, int *c) { // b 为乘数
int i, tmp, carry = 0;

for(i = N - 1; i >=0; i--) {
tmp = a[i] * b + carry;
c[i] = tmp % 10000;
carry = tmp / 10000;
}
}

void div(int *a, int b, int *c) { // b 为除数
int i, tmp, remain = 0;

for(i = 0; i < N; i++) {
tmp = a[i] + remain;
c[i] = tmp / b;
remain = (tmp % b) * 10000;
}
}

  • Java
public class BigNumber {
public static int[] add(int[] a, int[] b) {
int carry = 0;
int[] c = new int[a.length];

for(int i = a.length - 1; i >= 0; i--) {
c[i] = a[i] + b[i] + carry;
if(c[i] < 10000)
carry = 0;
else { // 进位
c[i] = c[i] - 10000;
carry = 1;
}
}

return c;
}

public static int[] sub(int[] a, int[] b) {
int borrow = 0;
int[] c = new int[a.length];

for(int i = a.length - 1; i >= 0; i--) {
c[i] = a[i] - b[i] - borrow;
if(c[i] >= 0)
borrow = 0;
else { // 借位
c[i] = c[i] + 10000;
borrow = 1;
}
}

return c;
}

public static int[] mul(int[] a, int b) { // b 为乘数
int carry = 0;
int[] c = new int[a.length];

for(int i = a.length - 1; i >=0; i--) {
int tmp = a[i] * b + carry;
c[i] = tmp % 10000;
carry = tmp / 10000;
}

return c;
}

public static int[] div(int[] a, int b) { // b 为除数
int remain = 0;
int[] c = new int[a.length];

for(int i = 0; i < a.length; i++) {
int tmp = a[i] + remain;
c[i] = tmp / b;
remain = (tmp % b) * 10000;
}

return c;
}

public static void main(String[] args) {
int[] a = {1234, 5678, 9910, 1923, 1124};
int[] b = {1234, 5678, 9910, 1923, 1124};
int[] c = BigNumber.add(a, b);

for(int i = 0; i < c.length; i++) {
System.out.print(c[i]);
}
System.out.println();
}
}
<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script> name="google_ads_frame" marginwidth="0" marginheight="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-9750319131714390&dt=1190264214656&lmt=1181153050&format=160x600_as&output=html&correlator=1190264214640&url=http%3A%2F%2Fcaterpillar.onlyfun.net%2FGossipCN%2FAlgorithmGossip%2FBigNumber.htm&ad_type=text_image&ref=http%3A%2F%2Fcaterpillar.onlyfun.net%2FGossipCN%2FAlgorithmGossip%2FAlgorithmGossip.htm&cc=382&ga_vid=109980960.1190165891&ga_sid=1190264183&ga_hid=225807379&ga_fc=true&flash=9&u_h=768&u_w=1024&u_ah=738&u_aw=1024&u_cd=32&u_tz=480&u_his=3&u_java=true" frameborder="0" width="160" scrolling="no" height="600" allowtransparency="allowtransparency">

<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script> name="google_ads_frame" marginwidth="0" marginheight="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-9750319131714390&dt=1190264214671&lmt=1181153050&prev_fmts=160x600_as&format=160x600_as&output=html&correlator=1190264214640&url=http%3A%2F%2Fcaterpillar.onlyfun.net%2FGossipCN%2FAlgorithmGossip%2FBigNumber.htm&ad_type=text_image&ref=http%3A%2F%2Fcaterpillar.onlyfun.net%2FGossipCN%2FAlgorithmGossip%2FAlgorithmGossip.htm&cc=382&ga_vid=109980960.1190165891&ga_sid=1190264183&ga_hid=225807379&ga_fc=true&flash=9&u_h=768&u_w=1024&u_ah=738&u_aw=1024&u_cd=32&u_tz=480&u_his=3&u_java=true" frameborder="0" width="160" scrolling="no" height="600" allowtransparency="allowtransparency">

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值