c/c
- 当我们做运算时,在数据范围特别大的时候,运用运算符往往得不到正确结果,这是为什么?在c+ +中,每一实数变量都是有数据存储范围的,例如-231<int<231-1.一旦超出范围时,它就会自动存入一个神奇的数,于是发生错误,而当数据高到恐怖即使是long long甚至-int128都不及时,我们就要用上高精度算法。
- 数组搞定高精度数字
我们用到的方法是开数组来存储,若想存一个20002000位的数,就把数组开到20002000以上。*我们用数组的每一个空间来存每一位数的那个数字。*我们并不选择直接一个个输入,我们选择利用字符串,比如说我们现在要存123这个数,把它存进na数组里。像这样:
string a, b;
cin >> a >> b;
for(int i = a.size(); i > 0; i --)na[i] = a[a.size() - i] - '0';
for(int i = b.size(); i > 0; i --)nb[i] = b[b.size() - i] - '0';
这样做的原因是
- 字符串输入两个数字,我们可以直接地知道每个数字的长度,也就是位数(字符串a的长度为a.size(),依次类推)知道长度就可以直接给for循环服务。
- 小学计算
数字存进数组里了,那么接下来如何计算呢,答案是小学竖式计算。具体做法就是:*把两个数字的每一位对齐,从低位到高位,同一位逐次相减,如果减不够就向后一位借位,当一位减不够另一位时,就从高位借10过来再减,当然,高位会比原来少1。*用代码表示:
int maxl = max(a.size(), b.size());`
找到两个数中的最大位,为for循环服务
如果两个数位数不相等,相减也无妨,因为位数少的数那部分被0补齐,减下去不影响
for(int i = 1; i <= maxl; i ++)
{if(na[i] < nb[i])//减不够{
na[i + 1] --;//借位
na[i] += 10;//到低位去}
ans[i] = na[i] - nb[i];//相减}
- 输出问题、
- 坑点1
如果同10001-10000时,计算机会输出00001,这不是我们想要的。我们可以在结尾加上这么一句:
while(ans[maxl] == 0)maxl --;//如果最高位为0,就一直减小最高位,直到不为0为止。
- 坑点2
如果输出结果为0呢,我们加上这一句:
if(maxl < 1)cout << "0";//最大位小于1,也就是最高位为0时输出。//最高位为0,显而易见答案就为0了//这种情况下前面什么都不会输出,这里额外输出一个0倒也无伤大雅
- 坑点3
当结果小于0怎么办,稍微想一下,只有在数字 b>a的情况下,a−b才可能为负。于是我们可以用非常玄学的运算式:(a−b)=−(b−a),用以下代码实现:
bool pd;
if((a < b && a.size() == b.size()) || a.size() < b.size())
{
swap(a, b);//swap函数作用:交换两数
pd = true;//打上标记}
//----中间省略一堆计算代码-----
if(pd == true)cout << "-";
//b > a时,a - b < 0,打头输出负号
//----后面省略一堆输出代码-----