精华内容
下载资源
问答
  • c++高精度乘法,字符串做法,支持50000位两数相乘,希望大佬帮助改进。Thanks♪(・ω・)ノ
  • 1307:【例1.3】高精度乘法 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 4358 通过数: 1440 【题目描述】 输入两个高精度正整数M和N(M和N均小于100位)。求这两个高精度数的积。 【输入】 输入两个高精度正...
  • 高精度乘法

    2011-10-23 16:38:02
    此程序是一个计算高精度的c++程序,使用字符方法,利用数组存储。
  • C语言高精度乘法

    2013-07-21 20:02:46
    如何用C语言写高精度乘法高精度乘法需要用到函数调用,指针等知识
  • 1136高精度乘法.cpp

    2019-09-29 21:05:36
    高精度,是学C语言漫长的路上必须要学的一类程序,菜鸡博主大一刷OJ时候的存货
  • C语言实现高精度乘法

    2021-08-13 14:08:19
    大一小白尝试C语言高精度乘法 一、高精度乘法是什么 高精度乘法就是对于普通数据类型无法表示的大整数进行乘法运算。 二、为什么需要高精度乘法 在C语言中,常用的数据类型有int, long long, double等,但是这些数据...

    大一小白尝试C语言高精度乘法

    一、高精度乘法是什么

    高精度乘法就是对于普通数据类型无法表示的大整数进行乘法运算。

    二、为什么需要高精度乘法

    在C语言中,常用的数据类型有int, long long, double等,但是这些数据类型的大小有限,当输入的数据过大,这些数据类型就无法实现其功能,强行使用可能会出现错误。在这种情况下,我们需要高精度乘法来完成运算。

    三、如何实现高精度乘法

    为了更方便的理解高精度乘法,我们先从熟悉的竖式乘法开始。首先我们知道,电脑笨笨的,普通数据类型算不了大数乘法。但是小学的时候我们很聪明,学习了竖式乘法,表达是这样的。在这里插入图片描述
    过程是这样的,我们根据九九乘法表对于两位单独的数字进行运算,列在对应的位置上,最后进行累加并完成进位。

    所以理论上来说,我们可以用竖式乘法计算很大的数。

    四、实现

    于是我们有了高精度乘法的实现思路:

    1.输入

    2.各位相乘相加

    3.进位

    4.输出

    至于采取什么样的数据类型存储输入输出,答案显而易见,字符串是十分合适的。至此,我们有了大体的思路。那么就可以开始处理数据了。

    首先是输入的一些准备工作,我们需要两个字符串来存储因数,以及一个字符串来存储答案,为了方便计算,我们将char的数转变为int类型。

    void High_Precision_Multiplication(char c_number_1[], char c_number_2[], char c_answer[]) {
    	int i_number_1[Number_Size];//第一个数字
    	int i_number_2[Number_Size];//第二个数字
    	int i_answer[Number_Size];//结果
    	//可以在线处理
    	int length_1 = strlen(c_number_1);//第一个数字的位数(长度)
    	int length_2 = strlen(c_number_2);//第二个数字的位数(长度)
    	int length_3;//答案的位数
    	int i, j;
    	char temp;//用于逆转
    	memset(c_answer, 0, length_answer);
    	memset(i_number_1, 0, sizeof(i_number_1));
    	memset(i_number_2, 0, sizeof(i_number_2));
    	memset(i_answer, 0, sizeof(i_answer));
    	//完成初始化
    }
    

    逆转和数字转换

    	for (i = 0; i < length_1; i++) {
    		i_number_1[i] = c_number_1[length_1 - i - 1] - '0';
    	}
    	for (i = 0; i < length_2; i++) {
    		i_number_2[i] = c_number_2[length_2 - i - 1] - '0';
    	}
    	//完成逆转+数字转换
    

    竖式乘法

    	for (i = 0; i < length_1; i++) {
    		for (j = 0; j < length_2; j++) {
    			i_answer[i + j] += i_number_1[i] * i_number_2[j];
    		}
    	}
    	//完成相乘
    

    根据竖式乘法的规则我们知道,上面代码的第三行是成立的。

    进位

    	for (i = 0; i < length_1 + length_2 - 1; i++) {
    		if (i_answer[i] >= 10) {
    			i_answer[i + 1] += i_answer[i] / 10;
    			i_answer[i] %= 10;
    		}
    	}
    	//完成进位
    

    逆转和输出

    为了方便输出,我们将答案转换回字符,并逆转头尾

    	i = 0;
    	while (i_answer[i] || i < length_1 + length_2 - 1) {
    		i_answer[i] += '0';
    		i++;
    	}
    	//转换回字符
    	length_3 = i;
    	i = 0;
    	while (i < length_3 - i - 1) {
    		temp = i_answer[i];;
    		i_answer[i] = i_answer[length_3 - i - 1];
    		i_answer[length_3 - i - 1] = temp;
    		i++;
    	}
    	//逆转回去
    	for (i = 0; i < length_3; i++) {
    		c_answer[i] = i_answer[i];
    	}
    	//输出答案
    

    五、最后的代码

    将各部分代码合并,我们就得到了高精度乘法的函数

    void High_Precision_Multiplication(char c_number_1[], char c_number_2[], char c_answer[], int length_answer) {
    	int i_number_1[Number_Size];//第一个数字
    	int i_number_2[Number_Size];//第二个数字
    	int i_answer[Number_Size];//结果
    	//可以在线处理
    	int length_1 = strlen(c_number_1);//第一个数字的位数(长度)
    	int length_2 = strlen(c_number_2);//第二个数字的位数(长度)
    	int length_3;//答案的位数
    	int i, j;
    	char temp;//用于逆转
    	memset(c_answer, 0, length_answer);
    	memset(i_number_1, 0, sizeof(i_number_1));
    	memset(i_number_2, 0, sizeof(i_number_2));
    	memset(i_answer, 0, sizeof(i_answer));
    	for (i = 0; i < length_1; i++) {
    		i_number_1[i] = c_number_1[length_1 - i - 1] - '0';
    	}
    	for (i = 0; i < length_2; i++) {
    		i_number_2[i] = c_number_2[length_2 - i - 1] - '0';
    	}
    	//完成逆转+数字转换
    	for (i = 0; i < length_1; i++) {
    		for (j = 0; j < length_2; j++) {
    			i_answer[i + j] += i_number_1[i] * i_number_2[j];
    		}
    	}
    	//完成相乘
    	for (i = 0; i < length_1 + length_2 - 1; i++) {
    		if (i_answer[i] >= 10) {
    			i_answer[i + 1] += i_answer[i] / 10;
    			i_answer[i] %= 10;
    		}
    	}
    	//完成进位
    	i = 0;
    	while (i_answer[i] || i < length_1 + length_2 - 1) {
    		i_answer[i] += '0';
    		i++;
    	}
    	//转换回字符
    	length_3 = i;
    	i = 0;
    	while (i < length_3 - i - 1) {
    		temp = i_answer[i];;
    		i_answer[i] = i_answer[length_3 - i - 1];
    		i_answer[length_3 - i - 1] = temp;
    		i++;
    	}
    	//逆转回去
    	for (i = 0; i < length_3; i++) {
    		c_answer[i] = i_answer[i];
    	}
    	//输出答案
    	return;
    }
    

    六、结语

    这个函数接受三个char*,并将前两个数字相乘,输出到第三个字符串中,但是该函数没有输入检测,也没有输出检测。而且这个函数占用了很多不必要的内存空间,为了步骤清晰,进行了很多不必要的分划,时间效率也不高。仍有大量可以优化的空间。

    笔者是一位大一学生,因为手动实现高精度乘法的过程中出现了一些问题,因此写下这篇博客帮助理清思路。希望这篇博客能够帮助到更多刚接触C语言的同学们。如果文中有错误,欢迎指出。十分感谢各位的阅读!

    展开全文
  • C++ 的高精度乘法

    千次阅读 多人点赞 2020-02-21 15:52:31
    为什么需要高精度计算 对于 C++ 而言,最大的数据为 long long(64b,8位),对于超过 8B 的数据,C++ 没有对应的数据类型进行表示。...高精度乘法计算原理 在读小学时,我们做乘法都采用竖式方法,如图 1 ...

    为什么需要高精度计算

    对于 C++ 而言,最大的数据为 long long(64b,8位),对于超过 8B 的数据,C++ 没有对应的数据类型进行表示。所以我们需要知道高精度计算。更详细的解释,可以参考这个网页https://blog.csdn.net/justidle/article/details/104414459

    高精度乘法计算原理

    在读小学时,我们做乘法都采用竖式方法,如图 1 所示。 这样,我们可以写出两个整数相减的算法。

    我们就可以用 C++ 语言来模拟这个竖式减法的过程。我们可以考虑利用 C++ 的数组来存储对应数据,假设用数组 A 存储被减数 856 的每一位,具体来说就是 A1 存储个位 6,A2 存储十位 5,A3存储百位 8;类似数组 A 的结构,使用数组 B 存储减数 25;类似数组 A 的结构,使用数组 C 来存储对应的乘积 21400。两数相加的结果就如图 2 所示。这样理论上来说,我们就可以计算无限大的数据。如上图 2 所示,下表表示对应的存储方式。

     数组 A数组 B数组 C
    [0]650
    [1]520
    [2]8 4
    [3]  1
    [4]  2

    如上面的图 2 ,首先计算被乘数与乘数的个位数字的乘积,把结果保存到积数组中,然后再用被除数乘以乘数的十位数字,把结果退一位加到积数组中。每加一次乘积结果就进行一次进位处理,放在一个新组数里面。其方法与加法中的进位处理一样。

    C_{0}=C_{0}^{`} = A_{0}\ast B_{0}\\ C_{1}=C_{1}^{`}+C_{1}^{``} = A_{0}\ast B_{1}+A_{1}\ast B_{0}+JW_{next round}\\ C_{2}=C_{2}^{`}+C_{2}^{``} = A_{2}\ast B_{0}+A_{1}\ast B_{1}+JW_{next round}\\ C_{3}=C_{3}^{`}+C_{3}^{``} = A_{3}\ast B_{0}+A_{2}\ast B_{1}+JW_{next round}\\ \cdots \cdots

    关键点

    1a[i]*b[j] 应该累加到 i+j 的位置;

    2、累加总结果为: c[i+j] = a[i]*b[j]+jw+c[i+j];

    3、所以每次累加完后:

           1)带入下一位累加的进位: jw = c[i+j] / 10;

           2)本位实际数: c[i+j] %= 10

    高精度乘法实现

    思路

    1、定义存储数组。

    2、读入数据处理。

    3、从个位开始模拟竖式乘法的过程,完成整个乘法。

    4、删除前导 0 。所谓前导零,就是出现类似这样数据 01234,这个 0 实际是不需要的。

    5、输出结果。倒序输出减法的结果数组 C,因为我们的个位是存储在下标为 0 的地方。

    技术细节说明

    定义存储数组

    根据题目的要求定义数组。这个部分代码如下:

    const int MAXN = 1e5+4; //根据题目的最大值。+4为了防止A+B出现进位
    char s1[MAXN] = {};//存储字符串
    char s2[MAXN] = {};//存储字符串
    int a[MAXN] = {};//存储加数A
    int b[MAXN] = {};//存储加数B
    int c[2*MAXN] = {};//存储乘积

    读入数据并处理

    这里我们先考虑以下几种情况,即 -3*5=-15 或者 -4*8=-32 或者 -3*(-2)=6,也就是说,需要对输入数据的正负号进行判断。这个部分代码如下:

        scanf("%s %s", s1, s2);//读入字符串
    
        //处理负数
        bool flaga = false;//乘数a的符号
        if ('-'==s1[0]) {
            flaga = true;
            strcpy(s1, &s1[1]);//删除负号
        }
        bool flagb = false;//乘数b的符号
        if ('-'==s2[0]) {
            flagb = true;
            strcpy(s2, &s2[1]);//删除负号
        }
    
        //处理输出的负号
        if ((true==flaga && false==flagb) || (false==flaga && true==flagb)) {
            printf("-");
        }
    
        //处理乘数1
        int lena = strlen(s1);
        for (int i=0; i<lena; i++) {
            a[lena-i-1]=s1[i]-'0';
        }
    
        //处理乘数2
        int lenb = strlen(s2);
        for (int i=0; i<lenb; i++) {
            b[lenb-i-1]=s2[i]-'0';
        }

    模拟竖式乘法

    这个部分代码如下:

        //模拟竖式乘法
        int jw;//上一轮计算进位
        for (int i=0; i<lena; i++) {
            jw=0;
            for (int j=0; j<lenb; j++) {
                //交叉乘积
                c[i+j] = a[i]*b[j]+jw+c[i+j];//当前乘积+上次乘积进位+原数
                jw = c[i+j]/10;//处理进位
                c[i+j] %= 10;
            }
            c[i+lenb]=jw;//进位设置
        }

    删除前导零

    这个部分代码如下:

        //删除前导零
        int lenc=lena+lenb;
        for (int i=lenc-1; i>=0; i--) {
            //因为我们是从索引 0 开始,所以最高位是保存在 len-1
            if (0==c[i] && lenc>1) {
                //注意要有 lenc>1 这个条件。考虑特殊情况,加法结果为 00,我们实际要输出 0。
                lenc--;
            } else {
                //第一个不是零的最高位,结束删除
                break;
            }
        }

    输出计算结果

    采用倒序的方式输出,因为我们数据保存是倒序结构,也就是低位在前。

        //逆序打印输出
        for (int i=lenc-1; i>=0; i--) {
            printf("%d", c[i]);
        }
        printf("\n");

    例题和 AC 代码

    题目

    题目链接

    一本通 OJ:http://ybt.ssoier.cn:8088/problem_show.php?pid=1174,或者http://ybt.ssoier.cn:8088/problem_show.php?pid=1307

    我自己 OJ:http://47.110.135.197/problem.php?id=1034

    题目描述

    求两个不超过 200 位的非负整数的积。

    输入

    有两行,每行是一个不超过 200 位的非负整数,没有多余的前导 0。

    输出

    一行,即相乘后的结果。结果里不能有多余的前导 0,即如果结果是 342,那么就不能输出为 0342。

    样例输入

    12345678900
    98765432100

    样例输出

    1219326311126352690000

    分析

    题目告诉我们不超过 200 位,也就是 MAXN = 200+4。特别的地方要注意乘积的长度为 2*MAXN。

    AC 代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int MAXN = 200+4; //根据题目的最大值。+4为了防止A+B出现进位
    char s1[MAXN] = {};//存储字符串
    char s2[MAXN] = {};//存储字符串
    int a[MAXN] = {};//存储加数A
    int b[MAXN] = {};//存储加数B
    int c[2*MAXN] = {};//存储和B
    
    int main() {
        scanf("%s %s", s1, s2);//读入字符串
    
        //处理负数
        bool flaga = false;//乘数a的符号
        if ('-'==s1[0]) {
            flaga = true;
            strcpy(s1, &s1[1]);//删除负号
        }
        bool flagb = false;//乘数b的符号
        if ('-'==s2[0]) {
            flagb = true;
            strcpy(s2, &s2[1]);//删除负号
        }
    
        //处理输出的负号
        if ((true==flaga && false==flagb) || (false==flaga && true==flagb)) {
            printf("-");
        }
    
        //处理乘数1
        int lena = strlen(s1);
        for (int i=0; i<lena; i++) {
            a[lena-i-1]=s1[i]-'0';
        }
    
        //处理乘数2
        int lenb = strlen(s2);
        for (int i=0; i<lenb; i++) {
            b[lenb-i-1]=s2[i]-'0';
        }
        
        //模拟竖式乘法
        int jw;//上一轮计算进位
        for (int i=0; i<lena; i++) {
            jw=0;
            for (int j=0; j<lenb; j++) {
                //交叉乘积
                c[i+j] = a[i]*b[j]+jw+c[i+j];//当前乘积+上次乘积进位+原数
                jw = c[i+j]/10;//处理进位
                c[i+j] %= 10;
            }
            c[i+lenb]=jw;//进位设置
        }
    
        //删除前导零
        int lenc=lena+lenb;
        for (int i=lenc-1; i>=0; i--) {
            //因为我们是从索引 0 开始,所以最高位是保存在 len-1
            if (0==c[i] && lenc>1) {
                //注意要有 lenc>1 这个条件。考虑特殊情况,加法结果为 00,我们实际要输出 0。
                lenc--;
            } else {
                //第一个不是零的最高位,结束删除
                break;
            }
        }    
        
        //逆序打印输出
        for (int i=lenc-1; i>=0; i--) {
            printf("%d", c[i]);
        }
        printf("\n");
    
        return 0;
    }
    展开全文
  • 今天咱们的主角是高精度高精度乘法 咱们先回顾一下竖式乘法 我们先不急着进位,先来看看,对应位置上的数字都是这么来的。 对于不足位我们补充零后,不难发现,对应位置的最后答案,是由该位置起以后的全部...

    高精度加法以及高精度单精度乘法这里就不过多赘述了。

     今天咱们的主角是高精度高精度乘法

    咱们先回顾一下竖式乘法

     

     我们先不急着进位,先来看看,对应位置上的数字都是这么来的。

    对于不足位我们补充零后,不难发现,对应位置的最后答案,是由该位置起以后的全部位交叉相乘获得,这么说大家可能不是很明白。 

    以下一位为例:

    那么对应 4 2 下面的16 15 12 是怎么来的呢

    我们重新回忆一下竖式乘法过程:

     看到这里大家有没有一下子就明白了我刚刚的说法呢

    然后我们考虑结果有多少位

    除第一次乘得的结果对齐外,其他位乘得的结果都左移一位

    最后的结果长度 = 数a的长度+数b的长度 - 1;

    最后,我们加上前导零,这就是我们算法最终的样子。

     当然,最后的结果,我们还需要进位,值得注意的是,由于我们的取得的数不是很大,当数据比较大时,可能会对第一位产生进位,这时,我们的数据的最终长度需要在上面的结果上+1。

    至此,我们的高精度高精度乘法就结束了。

    由于我看博客一直秉承着:没有代码一律不看的原则。

    so:

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 3000;
    int x[N],y[N];
    int c[N];
    string a,b;
    int num;
    void mults()
    { 
    	num = a.size()+b.size()-1;
    	for(int i=0;i<num;i++)
    	{
    		for(int j=0;j<=i;j++)c[i] += x[j]*y[i-j];
    		if(c[i]>=10)
    		{
    			c[i + 1] += c[i] / 10;
          		c[i] %= 10;	
    		}
    	}
    	//去掉多余的前导零 
    	for(int i=num;i>0;i--)
    	{
    		if(c[i] == 0)num--;
    		else break;
    	}
    }
    int main()
    {
    	cin>>a>>b;
    	memset(x,0,sizeof(x));
    	memset(y,0,sizeof(y));
    	for(int i =a.size()-1;i>=0;i--)	x[a.size()-1-i]=a[i] -'0'; 	
    	
    	for(int i= b.size()-1;i>=0;i--) y[b.size()-1-i]=b[i] -'0'; 
    	
    	mults();
    	
    	for(int i=num;i>=0;i--)	 printf("%d",c[i]);
    	return 0;
    	
    } 

    今天的学习经验分享就到这里吧

    展开全文
  • poj1001高精度乘法

    2013-10-19 10:23:41
    Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the national debt is a taxing experience for many computer systems....
  • 对于要求很搞的C语言高精度乘法,相信很多人还没有用到过,应为在常规的应用中一般精度的乘法就可以满足我们的计算要求,今天一起来看看高精度乘法的实现方法吧。/*高精度乘法输入:两行,每行表示一个非负整数(不...

    对于要求很搞的C语言高精度乘法,相信很多人还没有用到过,应为在常规的应用中一般精度的乘法就可以满足我们的计算要求,今天一起来看看高精度乘法的实现方法吧。

    /*

    高精度乘法

    输入:两行,每行表示一个非负整数(不超过10000位)

    输出:两数的乘积。

    */

    #include

    #include

    #include

    #include

    #define MAX 10001

    int bigchenfa(int *sum,int *a,int *b,int lsum,int la,int lb)

    {

    int i,j,k ;

    memset(sum,0,sizeof(sum));

    lsum = 0 ;

    for(i=1 ; i<= la ; i ) /*用数组模拟运算*/

    for(j=1,lsum=i-1; j<= lb ; j )

    sum[ lsum] = b[j] * a[i] ;

    for(i=1 ; i<= lsum ; i )/*进位处理*/

    if (sum[i] >= 10)

    {

    if ( sum[lsum] >= 10)

    lsum ;

    sum[i 1] = sum[i] / 10 ;

    sum[i] %= 10 ;

    }

    return lsum ;

    }

    int main(void)

    {

    int a[MAX]={0},b[MAX]={0},sum[MAX*2]={0} ;

    int la=0,lb=0,lsum=0;

    int i,j ;

    char sa[MAX],sb[MAX] ;

    scanf(\"%s %s\",sa,sb);

    la = strlen(sa);

    lb = strlen(sb);

    for(i=1,j=la-1; i<= la ; i ,j--)

    a[i] = sa[j] - ’0’ ;

    for(i=1,j=lb-1; i<= lb ; i ,j--)

    b[i] = sb[j] - ’0’ ;

    lsum = bigchenfa(sum,a,b,lsum,la,lb) ;

    for(i=lsum ; i>= 1 ; i--) [Page]

    printf(\"%d\",sum[i]);

    printf(\" \");

    system(\"pause\");

    return 0 ;

    }

    本文来源:搜集于网络

    展开全文
  • 1307:【例1.3】高精度乘法
  • 高精度乘法 C语言

    2021-01-04 16:05:28
    高精度乘法 为什么需要高精度乘法 原因: 首先我们看一看C语言用到的表示整数的数据类型 1.int 2.long int 3.long long int 即使是最大的long long int 类型能表达的位数依然有限 所以需要该表处理更大数据的策略 ...
  • 二、高精度乘法; 2.1、模板: 2.2、用法: 2.3、例题: 三、高精度除法; 3.1、模板: 3.2、用法 3.3、例题 四、尾声; 一、前言 很高兴看见您来读我的博客,说来我们上次还在讲高精度加法和除法...
  • ^_^这道题目,要用的只是点就一个,高精度乘法运算,如果是C++的话,请用分治的方法,而对于java以及python而言,只需要直接调用对于高精度计算的函数即可,此处用了python的pow计算位数很简单,10^x + k = 2^p -1 -...
  • 高精度乘法实现

    2013-06-02 19:39:50
    一般的乘法大家都会计算,但是如果数据位十几亿,上百亿乃至上万亿相乘怎么办?这就需要高精度算法的技术了。本文档包含高精度乘法的具体实验代码,经过严格测试后的实验结果。非常有用哟
  • C++ 实现高精度乘法

    2021-04-14 23:35:12
    https://blog.csdn.net/weixin_44723496/article/details/109004329
  • 算法提高 高精度乘法 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 计算机真是最傻的东西;他都不能计算大于10^65-1的ab,请你帮这个“最傻”的东西过关,否则它就真的只认识1和0了。 输入格式 共两行; 第...
  • 高精度乘法 高精度算法,属于处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字。一般这类数字我们统称为高精度数,高精度算法是用计算机对于...
  • c++高精度乘法(大数乘法)

    千次阅读 2019-04-18 18:34:24
    高精度乘法 对于计算机无法用普通数据类型(如:longint)表示的大整数进行乘法运算,称为高精度乘法。 步骤 高精度乘法主要包括以下几个要求及过程 1、为了获取输入数字的每一位的值,包括个位,十位等,输入整型...
  • 高精度乘法 洛谷P1303 基础的结构体高精度 没有用全局变量 道理和a+b problem都差不多 模板题 #include<iostream> #include<string.h> using namespace std; #define ll long long #define maxsize 2560...
  • c++高精度乘法.cpp

    2021-05-01 15:25:06
    c++用高精度实现乘法

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 37,193
精华内容 14,877
关键字:

高精度乘法

友情链接: 15816QA5aGk32M9803.rar