高精度计算

1.求N!(0 ≤ N ≤ 10000)

当N很大时
C、C++中,最大的数据类型long long只有64位: 2^64=18446744073709551616,也不够

解题方法

  1. java能直接算:无限大,直到撑爆计算机内存
import java.util.*;
import java.math.*;
public class Main{
	public static void main(String[] args){
		Scanner input  = new Scanner(System.in);
		while(input.hasNext()){
			int n = input.nextInt();
			BigInteger num = BigInteger.ONE;
			for(int i=1;i<=n;i++)
				num = num.multiply(BigInteger.valueOf(i));
			System.out.println(num);
		}
	}
}
  1. 也可用C++的大数乘法
  2. C++中的万进制:用数组存数。从低位到高位,每四位存到一个数组元素中。

连java也处理不了的大数:hdu1061,n = 10^ 9,求n^n的最后一个数字
n = 10^ 9 :即使java能直接算,也会超时。
方案:
(1)数字太大:取模操作。
(2)计算量太大:用快速幂加速。

void multi(int a[],int n)
{
	//1.先乘进去
	for(int i = 1;i <= a[0];i++)
		a[i] *= n;
	//2.处理进位
	int i;
	for(i = 1;i <= a[0];i++){
		a[i + 1] += a[i] / R;
		a[i] %= R;
	}
	//3.处理高位进位
	while(a[i]){
		a[i + 1] = a[i] / R;//高位进位
		a[i++] %= R;
		a[0]++;
	}
}
int main()
{
	string s;int n;
	while(cin >> n){
		int m = s.length();
		int a[N] = {1,1},j = 1;
		for(int i = 2;i <= n;i++)
			multi(a,i);
		print(a);
	}
	return 0;
}
//输出大数a
void print(int a[])
{
	printf("%d",a[a[0]]);
	//中间的0必须有
	for(int i = a[0] - 1;i >= 1;i--)
		printf("%04d",a[i]);
	cout << endl;
}

2.

高精度数的存储,用字符串读入

void init(int a[])
{
	string s;
	cin>>s;//读入字符串s
	a[0]=s.length();
	//用a[0]计算字符串s的位数
	for(i=1;i<=a[0];i++)
		a[i]=s[a[0]-i]-'0';
		//将数串s转换为数组a,并倒序存储.
}

计算结果位数的确定

  1. 高精度加法: 两数之和的位数最大为较大数的位数加1;
  2. 高精度减法: 两数之差的位数最大为较大数的位数;
  3. 高精度乘法: 两数乘积的位数最大为两个因子的位数和
  4. 阶乘和乘方: 可利用对数运算来确定,2 ^ p的位数为:[log10(2^p)+1]=[p*ln2/ln10]+1
  5. 高精度除法: 两数相除的位数最大为较大数的位数减较小的位数加1

高精度数比较

比较数组a和b的大小关系,若a>b返回1,a

int compare (int a[],int b[])
{
	if (a[0]>b[0]) return 1;//a的位数大于b则a比b大
	if (a[0]0;i--) //从高位到低位比较
	{ 
		if (a[i]>b[i]) return 1;
		if (a[i]

高精度结果的输出

void print(int a[ ]) //打印输出
{
	int i;
	if (a[0]==0){
		cout<<0<0;i--)
		cout<

3.高精度加法

模拟手算
10进制

void jia(int a[],int b[]) //计算a=a+b
{ 
	int i,k;
	if(a[0]0) a[0]++;
	//修正新的a的位数(a+b最多只能的一个进位)
}

N进制运算
1、当前位规范由%10改为% n
2、进位处理由/10改为/n
3、其他运算规则不变

4.高精度减法

void jian(int a[],int b[])//计算a=a-b
{
	int flag,i;
	flag=compare(a,b); //调用比较函数判断大小
	if (flag==0) {
		a[0]=0;
		return;
	}
	//相等
	for(i=1;i<=a[0];i++) {
		if(a[i]

5.乘法运算

高精度数组a乘整数i

int chengshu(int a[],int k) //a=a*k,k是单精度数
{ 
	int i;
	if(k==0){
		for(i=0;i<=101;i++)
			a[i]=0;
		a[0]=0;
		return 0;
	} //处理k=0
	for(i=1;i<=a[0];i++)
		a[i]=a[i]*k;//先每位乘起来
	for(i=1;i<=a[0];i++) //处理进位
	{
		a[i+1]+=a[i]/10;
		a[i]%=10;
	}
	while(a[a[0]+1]>0)//处理最高位相乘的进位
	{ 
		a[0]++;
		a[a[0]+1]=a[a[0]]/10;
		a[a[0]]=a[a[0]]%10;
	}
	return 0;
}

两个高精度数组相乘

#include
using namespace std;
int a[101]={0},b[101]={0},c[101]={0};
void init(int a[])
{ 
	int i;
	string s;
	cin>>s;
	a[0]=s.length();
	for(i=1;i<=a[0];i++)
		a[i]=s[a[0]-i]-'0';
}
void print(int a[])
{
	int i;
	if (a[0]==0){
		cout<<0<0;i--) 
		cout<0&&c[c[0]]==0)
		c[0]--;
	return ;
}
int main()
{
	init(a);init(b);
	cheng(a,b,c);
	print(c);
	return 0;
}

6.除法运算

整数数组除以整数(a←a/b,a为整数数组,b为整数)

void chushu(int a[],int b,int c[],int d)//c=a/b,d=a%b
{ 
	int i;
	d=0; //余数初始化
	for(i=a[0];i>=1;i--)//按照由高位到底位的顺序,逐位相除
	{
		d=d*10+a[i]; //接受了来自第i+1位的余数
		c[i]=d/b; //计算商的第i位
		d=d%b;//计算第i位的余数
	}
	c[0]=a[0];
	while(c[0]>0&&c[c[0]]==0)
		c[0]--;//计算商的有效位数
	return ;
}

高精度除法x←x/y(被除数x和除数y为整数)

void chu(int a[],int b[],int c[])
{
	int i,j,tmp[101];
	c[0]=a[0]-b[0]+1;
	for (i=c[0];i>0;i--)
	{
		memset(tmp,0,sizeof(tmp));//数组清零
		numcpy(b,tmp,i); //将b拷贝到tmp的第i位,其余位是0
		while(compare(a,tmp)>=0){c[i]++;jian(a,tmp);}
		//用减法来模拟
	}
	while(c[0]>0&&c[c[0]]==0)
		c[0]--;
	return ;
}

你可能感兴趣的:(高精度计算)