大数阶乘问题

1- 计算200以内任意数的阶乘

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void fac_mult(int num1, int *num2, int len, int *ret, int ret_len)
{
    int index = 0;
    int ret_tmp = 0;
    int carry = 0;

    for (index=0; index<len; index++)
    {
        ret_tmp = num1 * num2[index];
        carry = ret_tmp / 10;
        ret_tmp %= 10;

        //ret[index] = ret_tmp + ret[index] ;
        //ret[index+1] = carry + ret[index+1];

        /* 将当前索引位结果和结果值中结果相加运算 */
        ret[index] = ret[index] + ret_tmp;
        carry += (ret[index] / 10);

        /* 保存当前结果 */
        ret[index] %= 10;
        ret[index+1] += carry;
    }
}


void test_print(int *ret, int ret_len)
{
    int len  = 0;
    int flag = 0;

    /* 打印测试结果 */
    len = ret_len;
    while(len--)
    {
        if ((ret[len] == 0) && (flag == 0))
            continue;
        flag = 1;
        printf("%d",ret[len]);
    }
    printf("\n");

}


void test_func_mult()
{
    int num1 = 3;
    int num2[3] = {1,6,3};
    int len  = sizeof(num2)/sizeof(int);
    int ret_len = len+1;
    int ret[ret_len];
    int flag = 0;
    memset(ret, 0, sizeof(ret));

    /* 计算阶乘和 */
    fac_mult(num1, num2, len, ret, ret_len);

    /* 打印测试结果 */
    len = ret_len;
    while(len--)
    {
        if ((ret[len] == 0) && (flag == 0))
            continue;
        flag = 1;
        printf("%d",ret[len]);
    }
    printf("\n");

}

void fac_add(int *num1_add, int *num2_add, int *ret, int len_max)
{
    int ret_tmp = 0;
    int carry = 0;
    int index = 0;

    for (index=0; index<len_max; index++)
    {
        /* 计算当前位置的和、进位 */
        ret_tmp = num1_add[index] + num2_add[index];
        carry = ret_tmp / 10;
        ret_tmp %= 10;

        /* 将当前索引位结果和结果值中结果相加运算 */
        ret[index] = ret[index] + ret_tmp;
        carry += (ret[index] / 10);

        /* 保存当前结果 */
        ret[index] %= 10;
        ret[index+1] += carry;
    }
}

void teset_fac_add()
{
    int num1[3] = {7,8,4};
    int num2[5] = {5,6,9,3,3};
    int len = 0;
    int len1 = sizeof(num1)/sizeof(int);
    int len2 = sizeof(num2)/sizeof(int);
    int len_max = len1 > len2 ? len1 : len2;
    int len_ret = len_max + 2;
    int ret[len_ret];
    int num1_add[len_max];
    int num2_add[len_max];
    int flag = 0;

    memset(ret, 0, sizeof(ret));
    memset(num1_add, 0, sizeof(num1_add));
    memset(num2_add, 0, sizeof(num2_add));

    memcpy(num1_add, num1, sizeof(num1));
    memcpy(num2_add, num2, sizeof(num2));

    /* 测试 */
    fac_add(num1_add, num2_add, ret, len_max);

    /* 打印测试结果 */
    len = len_ret;
    while(len--)
    {
        if ((ret[len] == 0) && (flag == 0))
            continue;
        flag = 1;
        printf("%d",ret[len]);
    }
    printf("\n");
}

int cnt_space(int num)
{
    if ((num <= 0) && (num > 200))
    {
        printf("input err\n");
        exit(1);
    }
    /* 计算num的阶乘比num-1阶乘最多多少位 */
    if (num < 10)
    {
        return 1;
    }
    else if (num < 100)
    {
        return 2;
    }
    else{
        return 3;
    }
}

void test_fac_2()
{
    int *fac_bf = NULL;
    int len_fac_bf = 1;
    int sizeof_fac_bf = 0;
    int len_fac_tmp = 0;
    int *fac_tmp = NULL;
    int sizeof_fac_tmp = 0;
    int *ret = NULL;
    int len_ret = 0;
    int index = 0;
    int num = 200;
    int add_space_len = 0;

    sizeof_fac_bf = sizeof(int) * len_fac_bf;
    fac_bf = malloc(sizeof_fac_bf);
    if (NULL == fac_bf)
    {
        printf("malloc fail\n");
        return ;
    }
    memset(fac_bf, 0, sizeof_fac_bf);
    fac_bf[0] = 1;

    for (index=2; index<num; index++)
    {
        /* 计算保存index阶乘比index-1阶乘需要多几位 */
        add_space_len = cnt_space(index);
        len_fac_tmp = len_fac_bf+add_space_len;

        sizeof_fac_tmp = len_fac_tmp * sizeof(int);
        fac_tmp = malloc(sizeof_fac_tmp);
        if (NULL == fac_tmp)
        {
            printf("malloc fail!\n");
            exit(1);
        }
        memset(fac_tmp, 0, sizeof_fac_tmp);

        /* 计算index阶乘结果,保存在fac_tmp中 */
        fac_mult(index, fac_bf, len_fac_bf, fac_tmp, len_fac_tmp);
        test_print(fac_tmp, len_fac_tmp);

        free(fac_bf);
        fac_bf = NULL;

        len_fac_bf = len_fac_tmp;
        fac_bf = fac_tmp;
    }

    free(fac_tmp);
    fac_tmp = NULL;

}

void test_fac()
{
    int fac1[1] = {0};

    test_fac_2();
}

int main(int argc, char *argv[])
{
    //test_func_mult();

    //teset_fac_add();


    test_fac();

    return 0;
}

2- 计算阶乘和问题

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void test_print(int *ret, int ret_len, int index);

void free_mem(void *mem_addr)
{
    if (NULL == mem_addr)
        return;
    free(mem_addr);
    mem_addr = NULL;
} 

void fac_mult(int num1, int *num2, int len, int *ret, int ret_len)
{
    int index = 0;
    int ret_tmp = 0;
    int carry = 0;

    for (index=0; index<len; index++)
    {
        ret_tmp = num1 * num2[index];
        carry = ret_tmp / 10;
        ret_tmp %= 10;

        //ret[index] = ret_tmp + ret[index] ;
        //ret[index+1] = carry + ret[index+1];

        /* 将当前索引位结果和结果值中结果相加运算 */
        ret[index] = ret[index] + ret_tmp;
        carry += (ret[index] / 10);

        /* 保存当前结果 */
        ret[index] %= 10;
        ret[index+1] += carry;
    }
}



void fac_add(int *num1_add, int *num2_add, int *ret, int len_max)
{
    int ret_tmp = 0;
    int carry = 0;
    int index = 0;

    for (index=0; index<len_max; index++)
    {
        /* 计算当前位置的和、进位 */
        ret_tmp = num1_add[index] + num2_add[index];
        carry = ret_tmp / 10;
        ret_tmp %= 10;

        /* 将当前索引位结果和结果值中结果相加运算 */
        ret[index] = ret[index] + ret_tmp;
        carry += (ret[index] / 10);

        /* 保存当前结果 */
        ret[index] %= 10;
        ret[index+1] += carry;
    }
}


int cnt_space(int num)
{
    if ((num <= 0) && (num > 200))
    {
        printf("input err\n");
        return -1;
    }
    /* 计算num的阶乘比num-1阶乘最多多少位 */
    if (num < 10)
    {
        return 1;
    }
    else if (num < 100)
    {
        return 2;
    }
    else{
        return 3;
    }
}

void fac()
{
    //int fac_init[1] = {1};
    int *fac_bf = NULL;
    int len_fac_bf = 1;
    int sizeof_fac_bf = sizeof(int) * len_fac_bf;;

    int *fac_tmp = NULL;
    int len_fac_tmp = 0;
    int sizeof_fac_tmp = 0;

    int len_max = 0;

    int *ret_tmp = NULL;
    int len_ret_tmp = len_fac_bf;
    int sizeof_ret_tmp = sizeof_fac_bf;

    int *ret = NULL;
    int len_ret = 0;
    int sizeof_ret = 0;
    int index = 0;
    int num = 100;
    int add_space_len = 0;

    int *num1_add = NULL;
    int *num2_add = NULL;

    fac_bf = malloc(sizeof_fac_bf);
    memset(fac_bf, 0, sizeof_fac_bf);
    fac_bf[0] = 1;
    ret_tmp = fac_bf;

    for (index=2; index<num; index++)
    {
        /* 计算保存index阶乘比index-1阶乘需要多几位 */
        add_space_len = cnt_space(index);
        if (-1 == add_space_len)
        {
            printf("fail!\n");
            free(fac_bf);
            fac_bf = NULL;
            return;
        }
        len_fac_tmp = len_fac_bf+add_space_len;

        sizeof_fac_tmp = len_fac_tmp * sizeof(int);
        fac_tmp = malloc(sizeof_fac_tmp);
        if (NULL == fac_tmp)
        {
            printf("malloc fail!\n");
            free(fac_bf);
            fac_bf = NULL;
            return;
        }
        memset(fac_tmp, 0, sizeof_fac_tmp);

        /* 计算index阶乘结果,保存在fac_tmp中 */
        fac_mult(index, fac_bf, len_fac_bf, fac_tmp, len_fac_tmp);
        //test_print(fac_tmp, len_fac_tmp, index);


        /* 计算前index阶乘和 */
        len_max = len_ret_tmp > len_fac_tmp ? len_ret_tmp : len_fac_tmp;
        len_ret = len_max + 2;
        sizeof_ret = sizeof(int) * len_ret;
        ret = malloc(sizeof_ret);
        if (NULL == ret)
        {
            printf("malloc fail\n");
            free(fac_tmp);
            free(fac_bf);
            fac_tmp = NULL;
            fac_bf = NULL;
            return;
        }
        memset(ret, 0, sizeof_ret);


        num1_add = malloc(sizeof(int) * len_max);
        num2_add = malloc(sizeof(int) * len_max);
        memset(num1_add, 0, (sizeof(int) * len_max));
        memset(num2_add, 0, (sizeof(int) * len_max));

        memcpy(num1_add, ret_tmp, sizeof_ret_tmp);
        memcpy(num2_add, fac_tmp, sizeof_fac_tmp);
        fac_add(num1_add, num2_add, ret, len_max);
		
		test_print(ret, len_ret, index);

		free_mem(num1_add);
		free_mem(num2_add);
		free_mem(fac_bf);

        len_fac_bf = len_fac_tmp;
        fac_bf = fac_tmp;

        ret_tmp = ret;
        len_ret_tmp = len_ret;
    }
	
	free_mem(fac_bf);
	free_mem(ret);
}



void test_fac()
{
    fac();  
}

int main(int argc, char *argv[])
{
    //test_func_mult();

    //teset_fac_add();


    test_fac();

    return 0;
}




void test_print(int *ret, int ret_len, int index)
{
    int len  = 0;
    int flag = 0;

    /* 打印测试结果 */
    printf("%d! = ", index);
    len = ret_len;
    while(len--)
    {
        if ((ret[len] == 0) && (flag == 0))
            continue;
        flag = 1;
        printf("%d",ret[len]);
    }
    printf("\n");

}


void test_func_mult()
{
    int num1 = 3;
    int num2[3] = {1,6,3};
    int len  = sizeof(num2)/sizeof(int);
    int ret_len = len+1;
    int ret[ret_len];
    int flag = 0;
    memset(ret, 0, sizeof(ret));

    /* 计算阶乘和 */
    fac_mult(num1, num2, len, ret, ret_len);

    /* 打印测试结果 */
    len = ret_len;
    while(len--)
    {
        if ((ret[len] == 0) && (flag == 0))
            continue;
        flag = 1;
        printf("%d",ret[len]);
    }
    printf("\n");

}


void teset_fac_add()
{
    int num1[3] = {7,8,4};
    int num2[5] = {5,6,9,3,3};
    int len = 0;
    int len1 = sizeof(num1)/sizeof(int);
    int len2 = sizeof(num2)/sizeof(int);
    int len_max = len1 > len2 ? len1 : len2;
    int len_ret = len_max + 2;
    int ret[len_ret];
    int num1_add[len_max];
    int num2_add[len_max];
    int flag = 0;

    memset(ret, 0, sizeof(ret));
    memset(num1_add, 0, sizeof(num1_add));
    memset(num2_add, 0, sizeof(num2_add));

    memcpy(num1_add, num1, sizeof(num1));
    memcpy(num2_add, num2, sizeof(num2));

    /* 测试 */
    fac_add(num1_add, num2_add, ret, len_max);

    /* 打印测试结果 */
    len = len_ret;
    while(len--)
    {
        if ((ret[len] == 0) && (flag == 0))
            continue;
        flag = 1;
        printf("%d",ret[len]);
    }
    printf("\n");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值