现在的计算机一般都是32或64位的, 代表这可以存储32或64个二进制位, c语言中定义的整数类型有很多, 他们都占4或8个字节,一个字节8个比特位, 所以存储整数最多可以有64个比特位,如果有符号位的话即signed long long可以存储2^63 - 1,即使是无符号位的unsigned long long也只能存储到2^64 - 1,2的10次方即1024约等于1000,所以2^60约等于10亿,2的64次方也可想而知, 尽管他们对我们日常来说已经很大, 但对于科学研究来说远远不足,那么怎么来存储一些更大的数字呢,顺序表在这就发挥很大作用了,把一个数的每一位存储在顺序表中,那么就可以储存那些非常大的整数了,这样这些大数的运算也可以用顺序表来实现了。
比如一个大数和一个一般数的加法
比如这两个数的相加,这里我用一个接口来实现
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* addToArrayForm(int* num, int numSize, int k, int* returnSize) {
int kSize = 0;
int temp = k;定义一个临时变量来存储一般数, 防止数据丢失。
while(temp){
kSize++;
temp /= 10;
}
int maxSize = numSize > kSize ? numSize : kSize;//求这两个数字的最大位数
int* arr = malloc(sizeof(int) * (maxSize + 1));//因为c语言不支持变长数组(c99除外),所以我们使用malloc在堆区开辟一个数组空间来存储相加的结果,因为两个数字相加又可能进位,所以数组的大小因为他们位数的最大值加一。
int arri = 0;//结果数组索引标记,因为两个数相加可能进位也可能不进位,所以不能确定结果的位数,即不知道最大索引的大小,所以我们可以先倒着存,然后再将数组转置这很容易实现。
int i = numSize - 1;
int next = 0;标记进位,若进位则改成-1加到下次结果中
int ret = 0;
while(maxSize--){
int a = 0;//如果数组的长度没有数的位数多,那么访问num[i]可能越界访问,为了避免这种情况,可以先定义一个变量为0,判断索引合法后才能赋值,不合法则为原来定义的1.
if(i >= 0){
a = num[i];
i--;
}
ret = a + k % 10 + next;每一位的大小为两个数字的那一位相加以及进位数
k /= 10;
if(ret > 9){
ret = ret - 10;
next = 1;
}
else{
next = 0;此处必须把进位数改为0!
}
arr[arri] = ret;
arri++;
}
循环的次数为最大位数,若最后一位进一则无法存储,所以在循环外判断一下是否进一来存储剩余位数
if(1 == next){
arr[arri] = 1;
arri++;
}
*returnSize = arri;c语言没有直接求数组长度的办法,所以用一个输出参数来返回它的长度
int left = 0;
int right = arri - 1;
逆转数组
while(left < right){
int temp = arr[right];
arr[right] = arr[left];
arr[left] = temp;
left++;
right--;
}
return arr;
}