我的大数相乘

 早就想写大数问题,一直拖到现在才把大数相乘给写了。我的思路:大数相乘建立在大数相加的基础上,类似二进制乘法,二进制直接移位相加,十进制先加后移位,再求和。

程序写地冗长,有时间再精减吧。

下一个写大数阶乘。

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

#define N 100

/***********************
 * 函 数 名:length()
 * 函数功能:计算字符串长度
************************/

int length(char * p)
{
    int len = 0;

    while( *(p + len) != '\0')
    {
        len++;
    }

    return len;
}

/****************************
 * 函 数 名:trans()
 * 函数功能:给字符串逆序
****************************/

void trans(char p[])
{
    int i,n;
    char tmp;

    n = length(p);

    for(i = 0; i < n/2; i++)
    {
        tmp = p[i];
        p[i] = p[n - 1 - i];
        p[n - 1 - i] = tmp;
    }
}

/****************************
 * 函 数 名:Myadd_big()
 * 函数功能:大数求和
****************************/
void Myadd_big(char str1[] ,char str2[] ,char str[])
{
    int i = 0, flag = 0;          // 下标变量 和 进位标志位
    int count1 , count2 ;         // 两个数的长度
    char tmp;
    
    count1 = length(str1);        
    count2 = length(str2);

    while( str1[i] != '\0' && str2[i] != '\0')    //一位一位相加 直到其中一个数结束
    {
                      
        tmp = str1[i] + str2[i] -'0' + flag;   
   
        // 如果字符tmp 大于 字符9 即相加产生了进位 则减去10 让它变为数字字符 
  
        if( tmp > '9')    
        {
            str[i] = tmp - 10;   // 保存 
            flag = 1;            //进位记为1
        }
        else
        {
            str[i] = tmp;        //没有进位 直接保存
            flag = 0;            //将进位记为0 (不可省)
        }

        i++;    //改变下标 将取两个数字串的下一位数 相加
    }

   //上面while循环结束后 至少有一个数字串被加完 下面 判断哪个被加完

    if(count1 == count2)      //两个数长度相同 判断最高位是否有进位
    {
        if(flag == 0)
        {
            str[i] = '\0';    //添加字符串标志 
        }
        else
        {
            str[i] = flag + '0'; //将进位位变为字符串 并保存为最高位
            i = i + 1;
            str[i] = '\0';     
        }
    }
    else if( count1 > count2 )   //两数一长一短 则将剩下的数与进位位相加
    {
        while( str1[i] != '\0')
        {
            tmp = str1[i] + flag;

            if( tmp > '9')
            {
                str[i] = tmp - 10;
                flag = 1;
            }
            else
            {
                str[i] = tmp;
		flag = 0;
            }

            i++;
        }

        if(flag == 0)
        {
            str[i] = '\0';
        }
        else
        {
            str[i] = flag + '0';
            i = i + 1;
            str[i] = '\0';
        }

    }
    else
    {
        while( str2[i] != '\0')
        {
            tmp = str2[i] + flag;

            if( tmp > '9')
            {
                str[i] = tmp - 10;
                flag = 1;
            }
            else
            {
                str[i] = tmp;
		flag = 0;
            }

            i++;
        }

        if(flag == 0)
        {
            str[i] = '\0';
        }
        else
        {
            str[i] = flag + '0';
            i = i + 1;
            str[i] = '\0';
        }
    }
    
    
}

void mymul_big(char str1[],char str2[],char res[])
{
    char tmp[N][2*N];
    char p;
    int i,j;

    res[0] = '\0';
    for(i = 0; i < N; i++)
    {
	tmp[i][0] = '\0';
    }

    i = 0;
    while(str2[i] != '\0')
    {
	j = i;

        for( p = '0' ; p < str2[i]; p++)
	{
            Myadd_big(str1,tmp[i],tmp[i]);
	}

	for(j = 0; j < i; j++)
	{
            res[j] = '0';
	}
        res[j] = '\0';
	strcat(res,tmp[i]);
	strcpy(tmp[i],res);
	res[0] = '\0';

	i++;
    }
  
    for(j = 0 ; j < i; j++)
    {
        Myadd_big(res,tmp[j],res);
    }
    
    trans(res);      // 逆序 将高位存在数组前面 待输出
    
}

int main()
{
    char str1[N],str2[N];  //串1、2 存放输入的数字  串str存放结果
    char res[2*N];

    printf("input a number:");
    gets(str1);

    printf("input a number:");
    gets(str2);

    trans(str1);      //将输入的数字串逆序 把低位存放在数组前面
    trans(str2);      

    mymul_big(str1,str2,res);  

    printf("result:");
 
    printf("%s\n",res);
 
    return 0;
}

检验的时候还发现大数求和中一个错误,都是懒惹的祸!

深入了解

https://blog.youkuaiyun.com/kiwi_berrys/article/details/52444024

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值