高精度算法【加减乘除】
创始人
2024-01-22 05:29:00
0

全文目录

  • 😍 前言
  • 😀 高精度加法
    • 🤔 操作步骤
    • 😵‍💫 代码模板
  • 😀高精度减法
    • 🤔操作步骤
    • 😵‍💫 代码模板
  • 😀高精度乘法
    • 🤔操作步骤
    • 😵‍💫 代码模板
  • 😀 高精度除法
    • 🤔 操作步骤
    • 😵‍💫 代码模板

😍 前言

在实际应用中,语言提供的数据类型的最大值或最小值可能不足以支撑我们所进行的运算,这时会导致数据的溢出,所以我们需要一种算法来保证运算结果的精度。高精度运算就是为了解决这一问题而来的。简单来说,就是将数据的每一位的分开,存放在数组中,通过对数组中的每个位置来进行相应的运算来的得到最终结果。

需要注意的是:

1、由于数据过大,所以在进行输入的时候一般用字符串来进行存放

2、在将数据的每一位放进数组中时,最好是反着存放,也就是从前往后,位数依次升高。

以存放753 和 964 为例:
在这里插入图片描述

这样存放的好处在于方便进位,当他们需要进位的时,可以直接尾插。如果是正着存放的话每次进位都需要头插,全部数据都要往后挪,过于麻烦。

在这里插入图片描述
同样的在读取数据的时候需要从后往前读取,或者数据逆置一下。


😀 高精度加法

两数相加,数据的前后顺序不影响结果。

但是根据手算,如果是小数加大数的话,不方便进位,所以在进行运算前先保证大数在前,小数在后。方便进行进位运算

🤔 操作步骤

高精度加法的步骤:

a + b

1、将a 和 b 每一位的数据存放分开在数组A 和 B 中(A.size >= B.size)

2、用 t 来保存上一位进位的结果

3、从前往后,同时遍历A 和 Bt 分别加上两个数据的低位A[i] 和 B[i] ,得到这一位的运算结果

4、将这一位的结果的个位尾插进数组中保存起来(一次只能去一位数) ———> (t % 10

5、记录这一位的进位结果 ———> (t / 10

6、重复上述步骤,直到 A 遍历完(因为 A.size >= B.size ,所以 A 结束了,运算也就结束了)

7、最后一次运算可能还需要进位,将 t 中保留的进位结果尾插进数组


😵‍💫 代码模板

     A+  B—————————C
// C = A + B, A >= 0, B >= 0, A.size >= B.size
vector add(vector &A, vector &B)
{if (A.size() < B.size())   // 保证位数大的 + 位数小的return add(B, A);vector C;		// 保存运算结果int t = 0;		// 保存上一次的进位结果for (int i = 0; i < A.size(); i ++){t += A[i];		// 依次相加if (i < B.size())  	// 防止越界t += B[i];C.push_back(t % 10);	// 取余数保存起来t /= 10;		// 保留进位}if (t) 		// 最后可能还会有进位C.push_back(t);return C;
}

😀高精度减法

两数相减,数据的前后顺序会影响结果的正负性,但是结果的绝对值都是一样的。

但是小数减大数的话,借位不方便操作。所以我们在进行减法前先保证大数在前,小数在后。如果输入的是小数减大数的话提前输出 -

🤔操作步骤

高精度减法的步骤:
a - b

1、将a b 中的每一位的数据存放分开在数组A 和 B

2、如果b > a 提前输出 - ,进行 b - a

3、用 t 来保存上一位借位的结果

4、从前往后,同时遍历A 和 BA[i]分别减去 tB[i] ,得到这一位的运算结果

5、将这一位的结果的个位尾插进数组中保存起来 ———> ((t + 10) % 10
因为t 有可能是负数,需要取 10 + tt 为正数时 (t + 10) % 10 == t % 10,所以t需要先加上 10,再进行取模

6、如果 t 为负数,将 t 置为 1 来标记这一位的借位情况

7、重复上述步骤,直到 A 遍历完(因为 a >= b ,所以 A 结束了,运算也就结束了)

8、循环结束后,以 156 - 150 为例,结果可能会存在前导0,所以需要进行前导0 的去除

😵‍💫 代码模板

// 在进行减法之前需要先判断A >= B,如果A < b,先输出'-',然后进行B - A
// 可能会有前导0
bool cmp(vector& a, vector& b)
{// 如果长度不相等的话就可以立马得出结果if (a.size() != b.size()) return a.size() > b.size();// a和b的长度相等的情况,因为数据是反着存放的,所以也要反着比较for (int i = a.size(); i >= 0; i--){if (a[i] != b[i])return a[i] >= b[i];}// a == b的情况return true;
}A-  B—————————C
// C = A - B, 满足A >= B, A >= 0, B >= 0
vector sub(vector &A, vector &B)
{vector C;for (int i = 0, t = 0; i < A.size(); i ++ ){t = A[i] - t;		// 向A[i] 借位if (i < B.size()) 	// 减后的值t -= B[i];	C.push_back((t + 10) % 10);		// 负数要取10-t的结果,正数的话还是原来的数据if (t < 0) 	  // 如果现在的值是负数,标记tt = 1;   else t = 0;}// 去除前导0while (C.size() > 1 && C.back() == 0) C.pop_back();return C;
}

😀高精度乘法

这里以一个大数 a 乘以一个小数 b 为例。

🤔操作步骤

高精度乘法的步骤:
a * b

1、将a 中的每一位的数据存放分开在数组A

2、用 t 来保存上一位的结果

3、从前往后,遍历A A[i]乘以 b 再加上 t,得到这一位的运算结果

4、将这一位的结果的个位尾插进数组中保存起来 ———> (t % 10

5、保留需要进位的数据(t /= 10

6、重复上述步骤,直到 A 遍历完,并且 t 为0时结束。

7、循环结束后,以 1547 * 0 为例,结果可能会存在前导0,所以需要进行前导0 的去除

😵‍💫 代码模板

     A*  B—————————C
// 可能出现大数乘以0的情况
// C = A * b, A >= 0, b >= 0
vector mul(vector &A, int b)
{vector C;int t = 0;for (int i = 0; i < A.size() || t; i ++ )  // t中可能还有数据,需要依次入数组{if (i < A.size()) t += A[i] * b;	// 得到本位的结果C.push_back(t % 10);	t /= 10;	// 保留需要进位的数据}// 去除前导0,可能会有*0的情况while (C.size() > 1 && C.back() == 0) C.pop_back();return C;
}

😀 高精度除法

这里以大数 a 除以 小数 b 为例。

因为除法是从高位开始运算的,所以得到的结果在入数组的时候也是从高位开始入的。为了跟前面的运算保持一致,所以需要在最后逆置数组。因为是一个位一个位进行运算,所以 a 中前几位可能除不尽 b ,所以需要去除前导0。

🤔 操作步骤

高精度除法的步骤:
a / b

1、将a 中的每一位的数据存放分开在数组A

2、用 r 来保存上一位的余数,

3、从前往后,遍历A r * 10 + A[i],得到这一位的除数

4、将这一位的结果尾插进数组中保存起来 ———> (r / b

5、保留余数(r %= b

6、重复上述步骤,直到 A 遍历完(剩下的余数不用管)

7、循环结束后,逆置数组。以 18954 / 88 为例,结果可能会存在前导0,所以需要进行前导0 的去除

😵‍💫 代码模板

	  	C————b|  a
// 因为除法是从高位开始运算的,所以入数组的时候也是从高位开始入,在最后需要逆置数组,
// 前几位可能比b小,除不尽b,需要去除前导0
// A / b = C ... r, A >= 0, b > 0
vector div(vector &A, int b, int &r)
{vector C;r = 0;for (int i = A.size() - 1; i >= 0; i -- ){r = r * 10 + A[i];C.push_back(r / b);r %= b;}reverse(C.begin(), C.end());while (C.size() > 1 && C.back() == 0) C.pop_back();return C;
}

完结散花🌈🌈🌈
在这里插入图片描述

相关内容

热门资讯

【金牛国投·上林语】本月优惠政... 【金牛国投·上林语】销售中心电话:028-87788752(中介勿扰) 售楼处价格,户型图,地址,电...
有效降低抑郁率、离婚率、犯罪率... 《家国情怀话家风》,郭文斌 著,百花文艺出版社出版 这是我在百花文艺出版社出版的第五本书,从《中国之...
男子出差中大奖,却被告知要&q... 出差途中顺手参与抽奖 运气爆棚中的大奖究竟算谁的? 近日 上海一男子因公出差 参加英伟达活动 现场意...
太原农商银行黄陵支行工作人员为... 来源:太原日报 11月20日,太原农商银行黄陵支行工作人员为群众讲解“整村授信”政策。近日,该行通...
东莞长安企业福音:“0租金”政... 在数字化办公趋势下,东莞长安天工智谷智造总部大厦以“智慧化+全配套”双轮驱动,为企业打造高效便捷的办...
城建发展:副总经理、总法律顾问... 雷达财经 文|冯秀语 编|李亦辉 11月21日,北京城建投资发展股份有限公司(证券简称:城建发展;证...
岂可以空白劳动合同规避法律 法院通过细致审查,识破了企业“制造同意”的虚假表象,还原了劳动者的真实意思表示。 20名班车司机入职...
中信证券:政策推动下 氢能有望... 人民财讯11月22日电,中信证券研报认为,“十五五”期间,在政策推动下,氢能有望逐步迈入产业化阶段。...
东营市齐鲁民商事调解中心:为民... 谁说调解工作总是针锋相对?近日,东营市齐鲁民商事调解中心成功化解了一起颇为“甜蜜”的纠纷。蜂农因某生...