c语言高精度乘法

当我们需要写出一个程序算出两数乘积时会很容易写出如图所示的代码

 从图中也可以看出这样的程序并不支持我们计算太大的数字  这是因为计算机内部直接使用int等数据类型储存数字是有范围限制的

 

当数据运算大小过大时 计算机将会出现溢出的情况 所以这时我们就需要高精度算法

所谓高精度算法就是使用数组 字符串完成对过大数字的运算和表达

而高精度乘法则是对我们在草稿纸上乘法运算的1:1还原

我将其分为 输入 拆分 乘算 进位 输出 五个部分

1>输入

 char a[1500],b[1500];
 scanf("%s%s",a,b);//以字符形式输入两个数字 不用&!

无需多言

2>拆分

eg:  1234*123-->  1  2  3  4 
                     1  2  3
                *
                --------------
int x=strlen(a);
int y=strlen(b);
int m[x],n[y];//用来储存拆分出来的每一位数字
 
int i, j;//利用for循环结合ascii表将ab两数组的字符形式数字每一位拆分出来变成普通数字
for (i = 0, j = x - 1; i < x; i++, j--)
    {
        m[i] = a[j] - '0';
    }
for (i = 0, j = y - 1; i < y; i++, j--)
    {
        n[i] = b[j] - '0';
    }

3>乘算

eg:  1  2  3  4  -->  4*3  3*3  2*3  1*3  
        1  2  3       4*2  3*2  2*2  1*2
    *                 4*1  3*1  2*1  1*1
    -----------
    int c[3000];//数组c用来储存计算后的每一位数
    for(i=0;i<3000;i++)//用for循环将c数组每一位填充成0
    {
        c[i]=0;
    }

    for (i = 0; i < x; i++)//将拆分后的数字进行乘法运算
    {
        for (j = 0; j < y; j++)
        {
        c[i + j] += m[i] * n[j];
        }
    }

4>进位

eg:  1  2  3  4  -->                      --> 1  2  3  4
        1  2  3                                  1  2  3
    *                                         *
    -----------                              -----------
                                              3  7  0  2
                                           2  4  6  8
                                        1  2  3  4
                                       -----------------
                                       1  5  1  7  8  2
 for (i = 0; i < x + y; i++)//处理进位
    {
       if (c[i] >= 10)
       {
        c[i + 1] += c[i] / 10;
        c[i] %= 10;
       }
    }

5>输出

  for (j = 2999; j > 0; j--)//确定最后一位数储存在哪个位置
    {
        if (c[j] != 0)
        break;
    }
    for (i = j; i >= 0; i--)//根据得出的位置输出
    {
    printf("%d", c[i]);
    }

最后 源代码

#include<stdio.h>
#include<string.h>
int main()
{
    char a[1500],b[1500];
    scanf("%s%s",a,b);//以字符形式输入两个数字 不用&!

    int x=strlen(a);
    int y=strlen(b);
    int m[x],n[y];//用来储存拆分出来的每一位数字
 
    int i, j;//利用for循环结合ascii表将ab两数组的字符形式数字每一位拆分出来变成普通数字
    for (i = 0, j = x - 1; i < x; i++, j--)
    {
        m[i] = a[j] - '0';
    }
    for (i = 0, j = y - 1; i < y; i++, j--)
    {
        n[i] = b[j] - '0';
    }

    int c[3000];//c用来储存计算后的每一位数
    for(i=0;i<3000;i++)//用for循环将c数组每一位填充成0
    {
        c[i]=0;
    }

    for (i = 0; i < x; i++)//将两个拆分后的数字进行乘法运算
    {
        for (j = 0; j < y; j++)
        {
        c[i + j] += m[i] * n[j];
        }
    }


    for (i = 0; i < x + y; i++)//处理进位
    {
       if (c[i] >= 10)
       {
        c[i + 1] += c[i] / 10;
        c[i] %= 10;
       }
    }

    for (j = 2999; j > 0; j--)//确定最后一位数储存在哪个位置
    {
        if (c[j] != 0)
        break;
    }
    for (i = j; i >= 0; i--)//根据得出的位置输出
    {
    printf("%d", c[i]);
    }
    return 0;
}

  • 8
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值