大数的运算——c语言版

现在的计算机一般都是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;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值