扩大
缩小

压位高精度的写法

// 2020/06/10 修正 HTML 源码

// 2021/12/25 发现这篇随笔阅读量破千了,二次修正 HTML 源码,并做了相关补充

压位高精度的写法

对于单位高精度算法,那么有没有可以加速、节省空间的做法呢?

显然是有的。

以前,存数字数组里面只存着一个数字,所以加减都是一位一位地加,进位也是一位一位地实现。

所以,我们尝试着将数字序列从一位变成多位。

比如高精度加法:

  • 如果压两位,我们就两位两位地存数字,运算时依然可以正常相加,但是相加的次数减半了;
  • 进位时,只需要将进位的数字除以 102,加到下一位就可以了。

所以,如果我们压八位(保证 LL 存的下的情况),那么时空复杂度的常数是 18

如,计算:13134987124987+192837918479

普通高精度

Step 1:分离数位

  1  3  1  3  4  9  8  7  1  2  4  9  8  7
+       1  9  2  8  3  7  9  1  8  4  7  9

Step 2:逐位相加

  1  3  1  3  4  9  8  7  1  2  4  9  8  7
+       1  9  2  8  3  7  9  1  8  4  7  9
————————————————————————————————————————————
  1  3  2 12  8 17 11 14 10  3 12 13 15 16

Step 3:进位

  1  3  1  3  4  9  8  7  1  2  4  9  8  7
+       1  9  2  8  3  7  9  1  8  4  7  9
————————————————————————————————————————————
  1  3  3  2  7  8  2  5  0  4  3  4  6  6

  所以答案为 13327825043466

压位高精度

Step 1:分离数位

   13    1349     8712    4987
+        1928     3791    8479

Step 2:各部分相加

   13    1349     8712    4987
+        1928     3791    8479
————————————————————————————————
   13    3277    12503   13466

Step 3:进位

   13    1349     8712    4987
+        1928     3791    8479
————————————————————————————————
   13    3278     2504    3466

 得出的答案为 13327825043466,和普通高精度算出的结果是一样的。


排坑

我们发现,有些数位进位之后会发生一些意想不到的结果:

例子:1598 + 9144

我们如果压 4 位,结果是:

      1598
+     9144
————————————————
   1  0472

但是,这个 0472 如果直接输出,是 472,于是就 WA 了。

所以可以这么写:

printf("%.4d", a);

这句话的作用是如果 a 不到 4 位就把不到的位用 0 填充后输出。

但是最高位所在的那段不能用 0 填充,不然结果将出现前导 0

所以比较好的做法,是先输出第一个数,再按照如上填充方式输出。


2021 年 12 月更新

压位高精度在某些运算中会极大提高程序效率,比如高精度乘法。

题目:给定两个大正整数 a,b,输出 a×b 的值。

范围:1a,b1050000

若我们使用普通高精度,那么根据乘法分配率,我们要两两枚举 a,b 的每一位并进行乘法,最后进位。

这么做的运算次数时 500002 级别的,不优秀。

但如果我们压位(以压 9 位为例),那么我们相当于把这个数字看作 109 进制的数字,在这个进制下该数的位数最多为 500009

然后可以对每个 109 进制的数字两两运算,复杂度就降为 50000292,是原来的几十分之一,在某些题目就能过掉更多的数据。

当然注意一些细节:

  • 109×109=1018,注意开 long long;
  • 两个长度为 p,q 的正整数相乘,结果位数是 p+q 级别的,空间不要开小了!
posted @   HoshizoraZ  阅读(1758)  评论(3编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示