C++大数问题_大数是指计算的数值非常大或者对运算的精度要求非常高,用已知的数据类型无法精确

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

* 1
* 2
* 3


第四步:



(1,4= 4) (1,5= 5) (1,6= 6)
(2,4= 8) (2,5=10) (2,6=12)
(3,4=12) (3,5=15) (3,6=18)

4 13 28 27 18
. . . .

5 6 0 8 8

* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8


123\*456=56088   
 分析一下每一位的值是如何计算出来的,以下说的位都是从个位算起:


结果的第i位,是乘数的第i位乘以被乘数的1位,再加上乘数的第i-1位乘以被乘数的第2位,一起加到乘数的第1位乘以被乘数的第i位。   
 这样描述起来有点不明白,画个图就很清楚了:   
 123\*456的第3位:从乘数的第3位(1)起到第1位(3),按从右向左的方式   
 逐个乘以被乘数:   
 1\*6+2\*5+3\*4=28   
 再把进位加上就可以了。   
 即:计算结果的第i位(权值肯定为i,第1位也就是个位权值为0(pow(10, 0)))。等于乘数的第(i~0)位分别与被乘数的第(0~i)位相乘,因为这样每位相乘之后权值仍为i 。然后相加再加上前一位的进位,就是结果的第i位   
 到这里,已经可以得出一个通用的计算方法,把结果逐位计算出来。   
 通过上面的分析,我们知道了算法的核心思想,接下来就能把算法实现 



#include
#include
#include
#include
#include
using namespace std;

//C++大数相加
string BigNumAdd(const string& strNum1, const string& strNum2)
{
string strSum;
int len1 = strNum1.size()-1;
int len2 = strNum2.size()-1;
int bit = 0; //保存进位

//从结尾开始每位相加 
while (len1>=0 && len2>=0)
{
    //求每位的和(要把进位也加上) 
    int tmpSum = strNum1[len1]-'0' + strNum2[len2]-'0' + bit;
    //保存进结果 
    strSum += tmpSum % 10 + '0';
    //求进位 
    bit = tmpSum / 10;
    --len1;
    --len2; 
}

//两个整数长度不相等(肯定有一个已经加完了,不需要再额外加if来判断,因为while就可以判断)
while (len1 >= 0)
{
    //和上个while循环一样
    int tmpSum = strNum1[len1]-'0' + bit;
    strSum += tmpSum % 10 + '0';
    bit = tmpSum / 10;
    --len1; 
}
while (len2 >= 0) 
{
    //和上个while循环一样
    int tmpSum = strNum2[len2]-'0' + bit;
    strSum += tmpSum % 10 + '0';
    bit = tmpSum / 10;
    --len2; 
}

//最高位有进位
if (bit != 0)
    strSum += bit + '0'; 

//反转
reverse(strSum.begin(), strSum.end()); 

return strSum;

}

//C++大数相乘
string BigNumMultiply(const string& strNum1, const string& strNum2)
{
string strMultiply;
//两数相乘最大有m+n位
int bit = 0;
int len1 = strNum1.size()-1;
int len2 = strNum2.size()-1;

//计算每一位 
for (int i=0; i<len1+len2+2; ++i)
{
    //计算结果的第i位(权值肯定为i,第1位也就是个位权值为0(pow(10, 0))) 
    //等于乘数的第(i~0)位分别与被乘数的第(0~i)位相乘,因为这样每位相乘之后权值仍为i 
    //然后相加再加上前一位的进位,就是结果的第i位
    //然后%10得出第i位,/10得到进位
    int tmp = 0;
    for (int j=i; j>=0; --j)
    {
        //如果下标超出字符串的范围 j为num1的下标, i-j为num2的下标,然后两数相乘 
        if (j>len1 || (i-j)>len2)
            continue;

        //还要注意字符串数字的最高位在字符串的最低位所以得用len减去 
        tmp += (strNum1[len1-j]-'0') * (strNum2[len2-(i-j)]-'0');
    }
    //加上进位
    tmp += bit;
    //为了防止最后一位是0,但是却加上了
    if (tmp == 0 && i == len1+len2+1) 
        break;
    //求余得到结果的第i位
    strMultiply += tmp % 10 + '0';
    //计算新的进位
    bit = tmp / 10; 
}

//判断结果的最后一个字符如果是0的话说明可以删去
//if (strMultiply[strMultiply.size()-1] == '0')
// strMultiply[strMultiply.size()-1] = '\0';

//反转
reverse(strMultiply.begin(), strMultiply.end()); 

return strMultiply;

}

int main()
{
string str1;
string str2;
cin >> str1 >> str2;

//相加和相乘
cout << BigNumAdd(str1, str2) << endl;
cout << BigNumMultiply(str1, str2) << endl; 

int n;
cin >> n;

//阶乘 
string rlt("1");
string opNum;
for (int i=1; i<=n; ++i)
{
    //ss不可以定义在for循环外
    stringstream ss; 
    ss << i;
    ss >> opNum;

    rlt = BigNumMultiply(rlt, opNum); 
}
cout << rlt << endl;

return 0;

}

* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
* 15
* 16
* 17
* 18
* 19
* 20
* 21
* 22
* 23
* 24
* 25
* 26
* 27
* 28
* 29
* 30
* 31
* 32
* 33
* 34
* 35
* 36
* 37
* 38
* 39
* 40
* 41
* 42
* 43
* 44
* 45
* 46
* 47
* 48
* 49
* 50
* 51
* 52
* 53
* 54
* 55
* 56
* 57
* 58
* 59
* 60
* 61
* 62
* 63
* 64
* 65
* 66
* 67
* 68
* 69
* 70
* 71
* 72
* 73
* 74
* 75
* 76
* 77
* 78
* 79
* 80
* 81
* 82
* 83
* 84
* 85
* 86
* 87
* 88
* 89
* 90
* 91
* 92
* 93
* 94
* 95
* 96
* 97
* 98
* 99
* 100
* 101
* 102
* 103
* 104
* 105
* 106
* 107
* 108
* 109
* 110
* 111
* 112


![img](https://img-blog.csdnimg.cn/img_convert/bb6a0e3d87403f9663f8e64c2b122583.png)
![img](https://img-blog.csdnimg.cn/img_convert/cff6f8483668a1d7452a549523c89d32.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

存中...(img-SleQuiFI-1715762431442)]
[外链图片转存中...(img-77NYz2yB-1715762431442)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值