蒟蒻的学习记录第四周

C语言实现高精度算法


前言.为什么需要高精度算法:在我们写代码时, 有时会处理一些较大数的运算,这些数甚至超过了unsigned long long的范围:
(0~2^64-1=18446744073709551615)。
此时需要用字符串数组来存储数字,运算时需要特殊的算法进行运算,称为高精度算法。 高精度算法本质上是模拟数字的运算

一级目录 高精度加法

在写高精度加法之前,先让我们回顾一下小学(或者是幼儿园)就学过的加法公式:

演示1985
+2566
每位数分别相加3 14 14 11
大于十则进一位4 4 5 1

其结果就是:1985+2566=4451
高精度加法正是模拟了这个运算过程,代码实现如下:

#include<stdio.h>
#include<string.h>
#define max 1000
int main(void)
{
	char str[max]; 
	int arr1[max]={0},arr2[max]={0};//初始化数组
	int len1,len2,len,i;
	scanf("%s",str);
	len1=strlen(str);
	for(i=0;i<len1;i++)
		arr1[i]=str[len1-1-i]-'0';//这里将数字倒置输入数组方便计算
	scanf("%s",str);
	len2=strlen(str);
	for(i=0;i<len2;i++)
		arr2[i]=str[len2-1-i]-'0';
	len=(len1>len2)?len1:len2;//比较两个数的位数,取最大位数
	for(i=0;i<len;i++)
	{
		arr1[i]+=arr2[i];//每位分别相加
		arr1[i+1]+=arr1[i]/10;//如果这位大于10,则进一
		arr1[i]%=10;//留下个位数
	}
	len++;
	if((arr1[len]==0))//判断最高位是否为零
		len--;
	for(i=len;i>=0;i--)
		printf("%d",arr1[i]);
	return 0;				
}

二级目录 高精度乘法

高精度乘法的原理也是对每位分别进行计算,思路基本与高精度加法相同
a、通过两个字符串输入两个整数;
b、引人两个数组,将两个整数通过一定的运算,分别将每一位的数字储存进数组中;
c、进行每一位的运算;
d、处理进位;
e、输出结果;
代码实现如下:

#include<stdio.h>
#include<string.h>
#define max 1000
int main(void)
{
	char str[max];
	int arr1[max]={0},arr2[max]={0},arr[2*max]={0};//新引入一个数组用来存放两数相乘的结果
	int len1,len2,len,i,j;
	scanf("%s",str);
	len1=strlen(str);
	for(i=0;i<len1;i++)
		arr1[i]=str[len1-1-i]-'0';
	scanf("%s",str);
	len2=strlen(str);
	for(i=0;i<len2;i++)
		arr2[i]=str[len2-1-i]-'0';
	for(i=0;i<len1;i++)
	{
		for(j=0;j<len2;j++)
		arr[i+j]+=arr1[i]*arr2[j];
		if(arr[i]>=10)
		{
			arr[i+1]+=arr[i]/10;
			arr[i]%=10;
		}
	}
	len=len1+len2;//两个自然数的积的位数,等于这两个数的位数的和,或者比这个和少1。
	if(arr[len-1]==0)
	len--;
	for(i=len-1;i>=0;i--)
		printf("%d",arr[i]);
	return 0;				
} 

三级目录 高精度加法与乘法的综合应用—求100以内数的阶乘和

题目链接:100以内阶乘和
在这里插入图片描述

这道题乍看很简单,似乎只要用一个循环就能解决,但如果真这样写了只能得50分,原因正如我们一开始所讲,数据过大超出了数据类型所能存储的范围,因此只能用高精度模拟运算解决。

#include<stdio.h>
#include<string.h>
#define max 1000
int main(void)
{
	int n,i,j,k,book;
	scanf("%d",&n);
	int arr1[max]={1},arr2[max]={1};//想想看这里为什么两个都要初始化为1
	for(i=2;i<=n;i++)//用i表示阶乘和
	{
		for(j=0;j<=101;j++)
		arr2[j]*=i;//高精度乘法求阶乘
		for(j=0;j<=101;j++)
		{
			if(arr2[j]>=10)
			{
				arr2[j+1]+=arr2[j]/10;
				arr2[j]%=10;
			}
		}
		for(k=0;k<=101;k++)//高精度加法将阶乘相加
		{
			arr1[k]+=arr2[k];
			if(arr1[k]>=10)
			{
				arr1[k+1]+=arr1[k]/10;
				arr1[k]%=10;
			}			
		}
	}
	for(i=100;i>=0;i--)//去掉最高位的零
	{
		if(arr1[i]!=0)
		{
			book=i;
			break;
		}
	}
	for(i=book;i>=0;i--)//输出
		printf("%d",arr1[i]);
	return 0;	
}

高精度减法与除法的实现相对于加法和乘法来说复杂一些,我们留到下篇文章再讲。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值