C:高精度的加法与乘法

什么是高精度运算?

实际上高精度就是说参与运算的数据和运算结果的范围,超出标准数据类型能表示的数据大小范围的运算。这个时候,如果要得到正确的计算结果,显然不能依靠普通方法实现了。而要在普通运算原理的基础上,加以辅助算法来实现超大数据的计算。例如:求两个100位的数据的和,或者计算两个100位的数字乘积。这时就要用到高精度算法了。

高精加:

思绪

  1. 既然运算数超过了数据大小范围,我们选择用数组存储数字
  2. 将数组逆序存储,这样便于加法的运算
  3. 再将运算完成后的数组逆序打印(这样看起来就是顺序的)

代码如下:

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//结构体重命名
typedef struct {
	char data[1000];//一千位的高精(可自行拓展)
	int len;		//数字有多长
}HighAcc;

//逆序数组并将字符转化为数字
void dealNumber(HighAcc *h){
	int start = 0, end = strlen(h->data) - 1;
	char tmp;

	h->len = end + 1;//计算结构体中数组的长度
	for (; start <= end; start++, end--){//完成数字逆序存储
		tmp = h->data[start];
		h->data[start] = h->data[end] - '0';//将字符转化为数字
		h->data[end] = tmp - '0';
	}
}

//高精度加法
HighAcc add(HighAcc m_num1, HighAcc m_num2){
	HighAcc sum = { 0 };
	int i, tmp;
	
	//存储更长数组的长度
	int maxlen = m_num1.len >= m_num2.len ? m_num1.len : m_num2.len;

	for (i = 0; i < maxlen; i++){//高精加的算法
		tmp = m_num1.data[i] + m_num2.data[i] + sum.data[i];
		sum.data[i] = tmp % 10;//得到每一位的数
		sum.data[i + 1] = tmp / 10;//判断高位进多大的数
	}
	sum.len = maxlen + sum.data[maxlen];//得到sum 的长度
	return sum;
}

//数组再逆序打印
void printNumber(HighAcc h){
	int i;
	for (i = h.len - 1; i >= 0; i--){
		putchar(h.data[i] + '0');	//将数字转化为字符
	}
}

int main(){
	HighAcc num1 = { 0 };
	HighAcc num2 = { 0 };
	HighAcc sum;

	scanf("%s%s", num1.data, num2.data);

	dealNumber(&num1);
	dealNumber(&num2);

	sum = add(num1, num2);

	printNumber(sum);
	putchar('\n');

	system("pause");
	return 0;
}

代码生成图:
在这里插入图片描述

高精乘:

高精乘的实现原理:

  • 高精乘只需在高精加的基础上改一些算法,所以将他们写在一篇博客中。

代码如下:

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//结构体重命名
typedef struct {
	char data[1000];//一千位的高精
	int len;		//数字有多长
}HighAcc;

//数字逆序存储(数组从左到右乘)
void dealNumber(HighAcc *h){
	int start = 0, end = strlen(h->data) - 1;
	char tmp;

	h->len = end + 1;//计算结构体中数组的长度
	for (; start <= end; start++, end--){//完成数组逆序存储
		tmp = h->data[start];
		h->data[start] = h->data[end] - '0';//为了将字符转化为数字
		h->data[end] = tmp - '0';
	}
}

//数子再逆序打印(看起来就是顺序)
void printNumber(HighAcc h){
	int i;
	for (i = h.len - 1; i >= 0; i--){
		putchar(h.data[i] + '0');	//将数字转化为字符
	}
}

//高精乘算法
HighAcc mul(HighAcc m_num1, HighAcc m_num2){
	HighAcc sum = { 0 };
	int i, j, tmp;
	
	//如果两者中有一个为0直接返回0
	if ((m_num1.len == 1 && m_num1.data[0] == 0) || (m_num2.len == 1 && m_num2.data[0] == 0)){
		sum.len = 1;
		return sum;
	}

//高精乘算法核心
	for (i = 0; i < m_num1.len; i++){
		for (j = 0; j < m_num2.len; j++){
			tmp = m_num1.data[i] * m_num2.data[j] + sum.data[i + j];
			sum.data[i + j] = tmp % 10;
			sum.data[i + j + 1] += tmp / 10;
		}
	}
	sum.len = m_num1.len + m_num2.len - !sum.data[m_num1.len + m_num2.len - 1];//得到sum 的长度
	return sum;
}

int main(){
	HighAcc num1 = { 0 };
	HighAcc num2 = { 0 };
	HighAcc sum;

	scanf("%s%s", num1.data, num2.data);

	dealNumber(&num1);
	dealNumber(&num2);

	sum = mul(num1, num2);

	printNumber(sum);
	putchar('\n');

	system("pause");
	return 0;
}

代码生成图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值