c语言实现1024bit大数乘法(3)

记录大数相乘的一般思路,乘法只是正数的大数相乘,数组第0位代表数组长度。
z[1]=x[1]*y[1]
z[2]=x[1]*y[2] +x[2]*y[1]
z[3]=x[1]*y[3] +x[2]*y[2]+x[3]*y[1]

因此可得z[i]=x[i-j+1]*y[j], for j=1到 y[0], x[0]> i-j>=0
考虑到进为问题,得到如下程序

          Init(t);
		t[0] = x[0] + y[0] - 1;
		for (i = 1; i <= t[0]; i++)
		{
			sum = carry;
			carry = 0;
			for (j = 1; j <= y[0]; j++)
			{
				if ((i - j) >= 0 && (i - j) < x[0])
				{
					mul = x[i - j + 1];
					mul = (unsigned long long)mul * y[j];
					carry = carry + mul / 0x100000000;
					mul = mul & 0xffffffff;
					sum = sum + mul;
				}
			}
			carry = carry + sum / 0x100000000;
			t[i] = (unsigned int)sum;
		}

全部代码如下

/****************************************************************************************************
大数相乘
调用方式Mul(x,y,z)
返回值,z=x*y
*****************************************************************************************************/
void Mul_Long(unsigned int x[], unsigned long long y, unsigned int *z)
{
	unsigned int t[34];
	unsigned long long mul;
	unsigned int carry = 0;
	int i;
	Init(t);
	Mov_Big(x, t);
	for (i = 1; i <= x[0]; i++)
	{
		mul = x[i];
		mul = mul * y + carry;
		t[i] = (unsigned int)mul;
		carry = (unsigned int)(mul >> 32);
	}
	if (carry != 0)
	{
		t[0]++;
		t[t[0]] = carry;
	}
	i = t[0];
	while (t[i] == 0 && i > 1)     //这里有改动i>1 
	{
		t[0]--;
		i--;
	}
	Mov_Big(t, z);
}


void Mul_Big(unsigned int x[], unsigned int y[], unsigned int *z)
{
	unsigned int t[100];
	unsigned long long sum, mul = 0, carry = 0;
	unsigned int i, j;
	if (y[0] == 1)
		Mul_Long(x, y[1], z);
	else
	{
		Init(t);
		t[0] = x[0] + y[0] - 1;
		for (i = 1; i <= t[0]; i++)
		{
			sum = carry;
			carry = 0;
			for (j = 1; j <= y[0]; j++)
			{
				if ((i - j) >= 0 && (i - j) < x[0])
				{
					mul = x[i - j + 1];
					mul = (unsigned long long)mul * y[j];
					carry = carry + mul / 0x100000000;
					mul = mul & 0xffffffff;
					sum = sum + mul;
				}
			}
			carry = carry + sum / 0x100000000;
			t[i] = (unsigned int)sum;
		}
		if (carry != 0)
		{
			t[0]++;
			t[t[0]] = (unsigned int)carry;
		}
		i = t[0];
		while (t[i] == 0 && i > 1)//这里有改动 
		{
			t[0]--;
			i--;
		}
		Mov_Big(t, z);

	}

}

能直接运行的完整代码实现大数乘法,利用devc++进行编译使用

#include<stdio.h>
#define MAX 32

/***************************************************************************************************
初始化大数对象,且数组第一位是数组的实际长度
****************************************************************************************************/
void Init(unsigned int *x)
{
	int i;
	for (i = 1; i < MAX; i++)
		x[i] = 0;
	x[0] = 1;

}
/***************************************************************************************************
大数比较
调用方式Cmp(x, y)
返回值,若x<y返回 - 1;若x>y返回1; 若x = y返回0
*****************************************************************************************************/
int Cmp(unsigned int x[], unsigned int y[])
{
	int i;
	if (x[0] > y[0])
		return 1;
	if (x[0] < y[0])
		return -1;
	for (i = MAX - 1; i >= 1; i--)
	{
		if (x[i] < y[i])
			return -1;
		if (x[i] > y[i])
			return 1;
	}
	return 0;
}

/****************************************************************************************************
大数赋值
调用方式Mov(x,y)
返回值:y被赋值为x;
*****************************************************************************************************/
void Mov_Big(unsigned int x[], unsigned int *y)
{
	int i;
	for (i = 0; i <= x[0]; i++)
	{
		y[i] = x[i];
	}
	if (x[0] < MAX)
		for (i = x[0] + 1; i < MAX; i++)
		{
			y[i] = 0;
		}
}

void Mov_Long(unsigned long long x, unsigned int *y)
{
	int i;
	if (x > 0xffffffff)
	{
		y[0] = 2;
		y[1] = (unsigned int)x;
		y[2] = (unsigned int)(x >> 32);
	}
	else
	{
		y[0] = 1;
		y[1] = (unsigned int)x;
	}
	for (i = y[0] + 1; i < MAX; i++)
		y[i] = 0;
}

/****************************************************************************************************
大数相乘
调用方式Mul(x,y,z)
返回值,z=x*y
*****************************************************************************************************/
void Mul_Long(unsigned int x[], unsigned long long y, unsigned int *z)
{
	unsigned int t[34];
	unsigned long long mul;
	unsigned int carry = 0;
	int i;
	Init(t);
	Mov_Big(x, t);
	for (i = 1; i <= x[0]; i++)
	{
		mul = x[i];
		mul = mul * y + carry;
		t[i] = (unsigned int)mul;
		carry = (unsigned int)(mul >> 32);
	}
	if (carry != 0)
	{
		t[0]++;
		t[t[0]] = carry;
	}
	i = t[0];
	while (t[i] == 0 && i > 1)     //这里有改动i>1 
	{
		t[0]--;
		i--;
	}
	Mov_Big(t, z);
}


void Mul_Big(unsigned int x[], unsigned int y[], unsigned int *z)
{
	unsigned int t[100];
	unsigned long long sum, mul = 0, carry = 0;
	unsigned int i, j;
	if (y[0] == 1)
		Mul_Long(x, y[1], z);
	else
	{
		Init(t);
		t[0] = x[0] + y[0] - 1;
		for (i = 1; i <= t[0]; i++)
		{
			sum = carry;
			carry = 0;
			for (j = 1; j <= y[0]; j++)
			{
				if ((i - j) >= 0 && (i - j) < x[0])
				{
					mul = x[i - j + 1];
					mul = (unsigned long long)mul * y[j];
					carry = carry + mul / 0x100000000;
					mul = mul & 0xffffffff;
					sum = sum + mul;
				}
			}
			carry = carry + sum / 0x100000000;
			t[i] = (unsigned int)sum;
		}
		if (carry != 0)
		{
			t[0]++;
			t[t[0]] = (unsigned int)carry;
		}
		i = t[0];
		while (t[i] == 0 && i > 1)//这里有改动 
		{
			t[0]--;
			i--;
		} 
		Mov_Big(t, z);

	}

}


int main() 
{
	unsigned int a[33]={8, 0x7C66DDDD, 0xE8C4E481, 0x09DC3280, 0xE1E40869, 0x487D01D6, 0xF5ED0704, 0x62BF718F,   0x93DE051D };
	unsigned int b[33]={8, 0x0A3EA616, 0x0C464CD7, 0xFA602435, 0x1C1C00CB, 0x5C395BBC, 0x63106512, 0x4F21E607,  0x21FE8DDA};
	unsigned int c[100];
	Mul_Big(a,b,c);
	int i;
	  printf("a=   ");
	 printf("\n ");
	for(i=a[0];i>=1;i--)
    printf("%llx",a[i]);
    printf("\n ");
    printf("\n ");
     printf("b=   ");
 printf("\n ");
    for(i=b[0];i>=1;i--)
    printf("%llx",b[i]);
     printf("\n ");
  printf("\n ");
   printf("a*b=  ");
    printf("\n ");
	for(i=c[0];i>=1;i--)
    printf("%llx",c[i]);
    return 0;
	
}

在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值