预计阅读时间: 15.6 分钟
3904 字250 字/分
本文内容较新·4周前更新
最后更新: 2025年10月24日
前几天突发奇想在洛谷上找到一个题,说是计算50!显然这一已经超出了longlong的范围,在题解区看到了高精度算法,遂浅浅的研究了一点点高精度问题
那么,高精度的原理到底是什么呢?
实际上,高精度的原理是将数字储存在一个数组中,然后再对数组里的每一位进行计算,得到一个长度远超正常类型的巨大的数
For example:
#include <stdio.h>
int main(){
short a,b,c;
a = 32767;
b = 32767;
c = a + b;
printf("%hd",c);
}显然它是无法正确的得到合理的结果的,因为它溢出了
而数组就可以很好的救我们与水火之中,它的样子大概是这样的
对short a,b,我们以下面的方式将其倒序存储到一个数组里
| 0 | 1 | 2 | 3 | 4 |
| 7 | 6 | 7 | 3 | 2 |
代码实现也很简单
#include <stdio.h>
#define MAX_SIZE 500
#define ll long long
int num[MAX_SIZE];
int temp = 0;
void save_num(ll input, int num[]){
temp = 0;
while (input > 0 ){
num[temp] = input % 10;
input /= 10;
temp++;
}
}
int main(){
ll input;
scanf("%lld", &input);
save_num(input, num);
}我们在一个循环中,对这个数字不断地取余再除以10,然后放在列表里
大概就是第一次循环时,32767取余7,放在数组的0索引位置,然后再除以10,得到3276取余6,放在索引1的位置,以此类推,直到除以10结果为0时停止。
但是,新的问题来了,如果我们要保存一个负数呢?这时候,我的思路是使用一个结构体
#define MAX_SIZE 500
typedef struct titan_number{
int num[MAX_SIZE];
int is_negative;
int size;
} tn;结构体储存高精度数
在这里,我们定义了一个叫titan_number的结构体,其中包含一个数组num,一个正负属性is_negative和数组的长度size
那么这样,我们就可以非常稳健的存储一个大数了
#include <stdio.h>
#define MAX_SIZE 500
typedef struct titan_number{
int num[MAX_SIZE];
int is_negative;
int size;
} tn;
void save_number(tn* number,short input){
number->size = 0; //初始化长度为0
if (input < 0){
number->is_negative = 1; //取绝对值,并记录正负属性
input = -input;
} else{
number->is_negative = 0;
}
while (input > 0){
number->num[number->size] = input % 10; //循环分解
input /= 10;
number->size++;
}
}
void print_number(tn* number){
if (number->is_negative == 1){
printf("-");
}
for (int i = number->size - 1; i >= 0; i--){
printf("%d",number->num[i]);
}
}
int main(){
short input_1,input_2;
scanf("%hd",&input_1);
scanf("%hd",&input_2);
struct a,b;
save_number(&a,input_1); //为什么这里和下面的a b都要用取地址符,因为这些东西作为参数时,
save_number(&b,input_2); //会自动退化为指针,所以直接传指针即可
print_number(&a);
printf("\n");
print_number(&b);
}
评论