大数乘法运算

做算法题时实现的一份大数乘法运算代码。没来得及详细整理,读者可以参考一下。

代码可以在VS2005上直接运行。

#include "stdafx.h"
#include <stdio.h>
#include <string>
#include <iostream>

using namespace std;
#define OK     0
#define ERROR -1

/* 函数声明 */
void calc1(char* pcStrA, int iLenA, int* piTmp, int num);
void accumulate(int iIndex, int *piResult, int iLenResult, int *piTemp, int iLenTemp);
char* BignumMultiply(char* pcNumA,int iLenA,char* pcNumB,int iLenB,char* pcResult,int iLenResult); 

/*===============================================================
            调用calc1和accumulate函数计算大数相乘
===============================================================*/
char* BignumMultiply
(
    char* pcNumA,
    int iLenA,
    char* pcNumB,
    int iLenB,
    char* pcResult,
    int iLenResult
)
{
    int i     = 0;
    int j     = 0;
    int num   = 0;
    int index = 0;
    int *piTmp    = NULL;
    int *piResult = NULL;

    /* 分配临时结果的存放空间 */
    piTmp=(int*)malloc((iLenA+1)*sizeof(int));
    piResult=(int*)malloc(iLenResult*sizeof(int));
    memset(piTmp, 0, (iLenA+1)*sizeof(int));
    memset(piResult, 0, iLenResult*sizeof(int));

    for (i = iLenB - 1; i>=0; i--)
    {
        /* 获取乘数pcNumB中第i位的值 */
        num = pcNumB[i] - ‘0‘; 

        /* 计算被乘数与第i位的乘积,结果保存在piTmp整型数组中 */
        calc1(pcNumA,iLenA,piTmp,num); 

        /* 将piTmp数组中的值加到piResult数组中 */
        index++;
        accumulate(index,piResult,iLenResult,piTmp,iLenA+1);
    }
    //printf("\n%s\n", pcResult);

    /* 去掉piResult中第一个非零数字前的零 */
    i = 0;
    while (piResult[i++]==0); 

    /* 将整形数组piResult中的值转化成字符串存入pcResult中 */
    index = 0;
    for (j = i - 1; j < iLenResult; j++, index++)
        pcResult[index] = piResult[j] + ‘0‘;
    if (iLenResult == i - 1)
    {
        pcResult[1] = ‘\0‘;
    }
    else
    {
        pcResult[index] = ‘\0‘;
    }

    free(piTmp);
    free(piResult);
    return pcResult;
} 

/*===============================================================
                计算被乘数与乘数的某一位的乘积
===============================================================*/
void calc1
(
    char *pcStrA,
    int iLenA,
    int *piTmp,
    int num
)
{
    /* d两个位的乘积结果,remainder余数,carry进位 */
    int i         = 0;
    int result    = 0;
    int remainder = 0;
    int carry     = 0; 

    /* 从被乘数字符串‘\0‘的前一位算起 */
    for (i = iLenA - 1; i >= 0; i--)
    {
        result = pcStrA[i] - ‘0‘;
        result *= num;
        remainder = (result + carry) % 10;
        carry = (result + carry) / 10;
        piTmp[i+1] = remainder;
    }
    if (carry)
        piTmp[0] = carry;
    else
        piTmp[0] = 0;
} 

/*===============================================================
将被乘数与乘数中一位数字的乘积结果计入res数组中
==============================================================*/
void accumulate
(
    int iIndex,
    int *piResult,
    int iLenResult,
    int *piTemp,
    int iLenTemp
)
{
    int i = 0;
    int j = 0;
    int m = 0;
    int n = 0;
    int remainder = 0;    //余数
    static int carry=0;
    for (j = iLenTemp - 1, i = 0; j >= 0; j--, i++)
    {
        m = piTemp[j];
        n = piResult[iLenResult-iIndex-i];
        if (m + n + carry >= 10)
        {
            remainder = (m + n + carry) % 10;
            carry = 1;
        }
        else
        {
            remainder = m + n +carry;
            carry = 0;
        }
        piResult[iLenResult - iIndex - i] = remainder;
    }
}

/*****************************************************************************
 Prototype    : multiply
 Description  : 两个任意长度的长整数相乘, 输出结果
 Input Param  :
                const std::string strMultiplierA  乘数A
                const std::string strMultiplierB  乘数B
 Output       :
                std::string strRst            乘法结果
 Return Value :
                int                       0  正确
                                         -1  异常
*****************************************************************************/
int multiply (const std::string strMultiplierA,const std::string strMultiplierB, std::string &strRst)
{
    int i = 0;
    int j = 0;
    int lenA = 0;
    int lenB = 0;
    int lenResult = 0;
    char *pcNumA = NULL;
    char *pcNumB = NULL;
    char *pcResult = NULL; /* 计算两个字符串的长度,及存储结果所需要的空间 */ 

    lenA = (int)strMultiplierA.length();
    lenB = (int)strMultiplierB.length();
    if (0 == lenA || 0 == lenB)
    {
        return ERROR;
    }

    pcNumA = (char*)strMultiplierA.c_str();
    pcNumB = (char*)strMultiplierB.c_str();
    lenResult = lenA + lenB + 1; /* 分配并初始化字符串数组 */
    pcResult = (char*)malloc(lenResult * sizeof(char));
    memset(pcResult, 0, lenResult);
    for (i = 0; i < lenResult-1; i++)
        *(pcResult + i) = ‘0‘; /* 计算并输出计算结果 */

    //printf("The result is: %s",BignumMultiply(pcNumA,lenA,pcNumB,lenB,pcResult,lenResult));
    BignumMultiply(pcNumA,lenA,pcNumB,lenB,pcResult,lenResult);
    for (i = 0; i < (int)strlen(pcResult); i++)
    {
        strRst += pcResult[i];
    }
    //printf("\n%s\n", pcResult);
    free(pcResult);
    return OK;
}

int main(void)
{
    string str1 = "111111";
    string str2 = "222222";
    string str3;
    multiply(str1, str2, str3);
    cout << str1 << " * " << str2 << " = ";
    cout << str3 << endl;
    return 0;
}

大数乘法运算

时间: 2024-10-08 08:09:08

大数乘法运算的相关文章

四:大数运算-乘法运算

问题:大数-乘法运算题目描述请计算两个整数相乘(数的范围为:0 <= num < 10 ^ 100)输入两个整数输出一个整数样例输入1000000010000000样例输出100000000000000 1 #include<stdio.h> 2 #include<string.h> 3 #define M 1000000 4 int Inter_Sum[M]; 5 int Inter_jie[M]; 6 int g; 7 //char Inter_Char[M]; 8

大数加法、减法、乘法

大数四则运算--C++实现 大数处理--c++实现 本课题来自我的c++编程作业,文章利用大数处理类,类名:hugeNumber来对大数(编译器自定义的数值类型无法处理的数)进行四则运算(大数加法.大数减法及大数乘法的运算,除暂时没实现)和按精度四舍五入,自定义科学计数法等.内容广泛涉及运算符重载.字符连接.字符加减和字符乘除等作者原创函数.重要提示:本文涉及的所有函数使用的进制皆为10进制.(备注:已将该博客搬迁至CSDN) 一.解题思路 1 核心思想 文章用hugeNumber类对大数进行操

笔试题56. LeetCode OJ (43)

这个题是个大数乘法运算的题,两个乘数以string的形式给出,求他们相乘的结果,题目给的限制条件是: 1.所给的数字可以任意的大,但是不为负数 2.不能将题目所给的string转化为整数 3.不能引入大数运算相关的库 从题目的描述中我知道了这个题让我们自己去实现大数运算的乘法,就是这么个意思,那么我们开始吧:在纸上算的时候我们都会,可是用程序去做的时候就比较难了吧,而且乘法运算从右往左运算的,我们怎么往string的头部插入一个字符串呢?不用担心,我们请看下图: 既然从右往左运算的时候字符串不好

ACM学习历程—51NOD1028 大数乘法V2(FFT)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1028 题目大意就是求两个大数的乘法. 但是用普通的大数乘法,这个长度的大数肯定不行. 大数可以表示点值表示法,然后卷积乘法就能用FFT加速运算了. 这道题是来存模板的. 代码: #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath>

Java大数处理类:BigInteger类和BigDecimal类

当我们要处理非常大的数据时,平常用的数据类型已不足以表示,在Java中有两个类BigInteger和BigDecimal分别表示大整数类和大浮点数类,这两个类在理论上只要计算机内存足够大就能够表示无线大的数.它们都在java.math.*包中,我们可以在API文档中进行查看: Java API 1.6 中文在线帮助文档 http://www.yq1012.com/api/ 实例: 1 import java.math.BigDecimal; 2 import java.math.BigInteg

大数相加相乘及阶乘

大数的相加相乘和阶乘操作都可能会导致结果的溢出,可以把它们转换成字符串,再进行运算,这里需要注意的是,习惯上的加法乘法运算都是从低位开始运算的,先计算个位,个位向高位进位,依次进行直到最高位.字符串表示一个数字的时候如"3476",它的低位数字在最大下标处,为了与习惯上的操作保持一致,可以先把字符串反转,求出结果之后再把结果反转回来即可.接下来的加法操作就使用了反转的方法,乘法操作也可以使用类似的反转,但本文的乘法操作没有使用反转.计算出的结果可以保存在字符串中,也可以保存在整型的数组

剑指offer编程题Java实现——面试题12相关题大数的加法、减法、乘法问题的实现

用字符串或者数组表示大数是一种很简单有效的表示方式.在打印1到最大的n为数的问题上采用的是使用数组表示大数的方式.在相关题实现任意两个整数的加法.减法.乘法的实现中,采用字符串对大数进行表示,不过在具体的计算中,还是要将字符串转化成字符数组来进行计算. 实现两个大数的加法,要考虑到两个问题,两个数的和的位数问题,以及如何处理两个数按位相加产生的进位问题.首先两个整数相加,两个数的和的位数最多比最大的整数的位数多1:这样和的位数就确定了.对于进位问题,我的做法是先进行按位相加,相加操作完成后再按照

大数常用计算模板及例题

一.模板&例题 [两个大数相加] string sum(string s1,string s2) { if(s1.length()<s2.length()) { string temp=s1; s1=s2; s2=temp; } int i,j; for(i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--) { s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0)); //注意细节 if(s1[i]-'0'>=10)

大数问题 加减乘除余 有参考部分网络代码如除法和减。其余原创。

大数问题集训会教案 大数问题,其实就是模拟运算,因为系统自带的int long bouble这些类型无法容纳百位千位的大数字,从而手动模拟运算过程,使用字符串来表示这样的超大数字,如果你会Java的话就简单多了,直接有一个大数类,可以像用函数一样直接调用,不过,那个是大三学滴. 大数问题适用的问题,一般是大数阶乘,大数加减乘除余方,这个嘛请参照南阳大数类型题,难度一般是省赛中最简单的3题之一. 废话不说,直接上思路先. 问题一:如何输入输出 问题二:小学生的个位与多位加法是怎么运算的?如何逆转字