C语言实现大整数加减运算详解语言实现大整数加减运算详解
大数运算,顾名思义,就是很大的数值的数进行一系列的运算。本文通过实例演示如何进行C语言中的大整数加
减运算,有需要的可以参考借鉴。
前言前言
我们知道,在数学中,数值的大小是没有上限的,但是在计算机中,由于字长的限制,计算机所能表示的范围是有限的,
当我们对比较小的数进行运算时,如:1234+5678,这样的数值并没有超出计算机的表示范围,所以可以运算。但是当我们在
实际的应用中进行大量的数据处理时,会发现参与运算的数往往超过计算机的基本数据类型的表示范围,比如说,在天文学
上,如果一个星球距离我们为100万光年,那么我们将其化简为公里,或者是米的时候,我们会发现这是一个很大的数。这样
计算机将无法对其进行直接计算。
可能我们认为实际应用中的大数也不过就是几百位而已,实际上,在某些领域里,甚至可能出现几百万位的数据进行运
算,这是我们很难想象的。如果没有计算机,那么计算效率可想而知。
由于编程语言提供的基本数值数据类型表示的数值范围有限,不能满足较大规模的高精度数值计算,因此需要利用其他方
法实现高精度数值的计算,于是产生了大数运算。本项目实现了大数运算的加、减运算。
一一. 问题提出问题提出
用C语言实现一个大整数计算器。初步要求支持大整数的加、减运算,例如8888888888888+1112=8888888890000或
1000000000000-999999999999=1。
C语言中,整型变量所能存储的最宽数据为0xFFFF FFFF,对应的无符号数为4294967295,即无法保存超过10位的整数。注
意,此处"10位"指数学中的10个数字,并非计算机科学中的10比特。浮点类型double虽然可以存储更多位数的整数,但一方
面常数字面量宽度受编译器限制,另一方面通过浮点方式处理整数精度较低。例如:
double a = 1377083362513770833626.0, b=1585054852315850548524.0;
printf("res = %.0f", a+b);
输出为res = 2962138214829621510144,而正确值应为2962138214829621382150。
既然基本数据类型无法表示大整数,那么只能自己设计存储方式来实现大整数的表示和运算。通常,输入的大整数为字符串形
式。因此,常见的思路是将大整数字符串转化为数组,再用数组模拟大整数的运算。具体而言,先将字符串中的数字字符顺序
存入一个较大的整型数组,其元素代表整数的某一位或某几位(如万进制);然后根据运算规则操作数组元素,以模拟整数运
算;最后,将数组元素顺序输出。
数组方式操作方便,实现简单,缺点是空间利用率和执行效率不高。也可直接操作大整数字符串,从字符串末尾逆向计算。本
文实现就采用这种方式。
二二. 代码实现代码实现
首先,给出几个宏定义和运算结构:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ADD_THRES (sizeof("4294967295")-2) //两个9位整数相加不会溢出
#define MUL_THRES (sizeof("65535")-2) //两个4位整数相乘不会溢出
#define OTH_THRES (sizeof("4294967295")-1) //两个10位整数相减或相除不会溢出
typedef struct{
char *leftVal;
char *rightVal;
char operator;
}MATH_OPER;
基于上述定义,以下将依次给出运算代码的实现。
加法运算主要关注相加过程中的进位问题:
void Addition(char *leftVal, char *rightVal,
char *resBuf, unsigned int resbufLen) {
unsigned int leftLen = strlen(leftVal);
unsigned int rightLen = strlen(rightVal);
unsigned char isLeftLonger = (leftLen>=rightLen) ? 1 : 0;
unsigned int longLen = isLeftLonger ? leftLen : rightLen;
if(resbufLen < longLen) { //possible carry + string terminator
fprintf(stderr, "Not enough space for result(cur:%u)!", resbufLen);
return;
}