大整数相乘和大数阶乘实现

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 大数相乘 , 采用字符串存储数据。
// 
// 每一位直接存储为 unsigned char 。存储实际值 不是ANSII码值
//              
// int big_num_multiply(unsigne char * base_num_1 size_t size_1,unsigned char * base_num_2,size_t size_2 , unsigned char * ret );
//
// 请务必确保 ret 指向空间足够大 , 否则后果自负 。 ret 指向空间 -->  ( size_1 + size_2 +1 )!
//
//     1  2  3  4  5
//       X
//           1  2  3
// --------------------
//     3  6 9   12 15
//   2 4  6 8   10
// 1 2 3  4 5
// --------------------
// 1 4 10 16 22 22 15 
// 1 5 1  8 4   3  5
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
void print_s_num(const char * s, size_t t)
{
    assert(t >= 0);
    size_t i;
    for(i =0; i < t ;  i++)
    {
        printf("%c",s[i] + '0');
    }
    printf("\n");
}




void str_to_num(unsigned char * base , size_t num)
{
    size_t i ;
    unsigned int one_part = 0;
    unsigned int add_part = 0;
    for(i = num ; i != 0 ; i --)
    {
        one_part = base[i-1] + add_part;
add_part = 0;
        if(one_part >= 10 )
{add_part = one_part / 10; one_part %= 10; }
base[i-1] = one_part;
    }
    assert(add_part == 0);
}


int delete_zero(unsigned char * base)
{
    int i = 0;
    while(!(*base))
    { i++; base ++ ; }
    return i;
}


void big_num_multiply(const unsigned char *base_num_1 ,size_t size_1,const unsigned char *base_num_2 , size_t size_2 , unsigned char *ret )
{
    size_t i, j;
    assert(size_1>0 && size_2 >0 && base_num_1 && base_num_2 && ret ); // 请输入有效数据 。 NULL 什么的就别来了 
    memset(ret, 0, size_1 + size_2 +1);
    unsigned char add_flag = 0;
    unsigned int one_part; 
    for( i = size_2; i !=0 ; i--)
    {
        for( j= size_1; j !=0 ; j-- )
{
   one_part = base_num_1[j-1] * base_num_2[i-1] + ret[i + j] +add_flag ;
   add_flag = 0;
   if(one_part > 255)
   { add_flag = one_part/10 ; one_part %= 10; }
            ret[i + j ] = (unsigned char )one_part; 
}
    }
    ret [1] = add_flag;
    str_to_num(ret,size_1+size_2+1);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// 阶乘 
//
// char * factorial(int n , int *size) 
// 务必释放返回的空间。!!
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////






char * factorial(int n , int *size)
{
    if( n == 1)
    {
        char *ret = malloc(1);
        *ret = 1;
*size = 1;
return ret;
    }
    else
    {
char base[10]; //神啊 你不能计算超过 *亿的数字的阶乘把 !!!
int num;
 
sprintf(base,"%d\0\0",n);
num = strlen(base);
int i = 0;
while(i<num)
{base[i] -= '0' ; i++;}
        printf("%s : %d\n",base,num);
char * res = factorial(n-1,size);
char * ret = malloc(*size +num+1);
        big_num_multiply(base,num,res,*size,ret);
int need_delete = delete_zero(ret);
char *ref = malloc(*size+num+1 - need_delete);
*size = *size+num+1 - need_delete;
memcpy(ref,ret+need_delete,*size);
free(ret);
free(res);
return ref;
    }
}




int main()
{
    int i ;
    char * res = factorial(32,&i);
    print_s_num(res,i);
    free(res);
   
    return 0;   
}




你可能感兴趣的:(大整数乘法,无限制阶乘)