什么是高精度运算?
实际上高精度就是说参与运算的数据和运算结果的范围,超出标准数据类型能表示的数据大小范围的运算。这个时候,如果要得到正确的计算结果,显然不能依靠普通方法实现了。而要在普通运算原理的基础上,加以辅助算法来实现超大数据的计算。例如:求两个100位的数据的和,或者计算两个100位的数字乘积。这时就要用到高精度算法了。
高精加:
思绪
- 既然运算数超过了数据大小范围,我们选择用数组存储数字
- 将数组逆序存储,这样便于加法的运算
- 再将运算完成后的数组逆序打印(这样看起来就是顺序的)
代码如下:
#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;
}
代码生成图: