简洁高效高精除法

2021-12-05 21:35

高精除法是高精里面比较麻烦的。并且实现思路很多,这里记录一个模拟竖式计算的思路。

如何模拟十进制的竖式除法?

图片替换文本

除法需要一位一位从高到低得出答案,用被除数减去答案和除数的积,得到余数作为下一轮被除数,继续获取下一位答案。

而获取余数的时候,我们将这一位的答案乘上除数,并于正在求解的这一位对齐后相减即可。

如何具体获得每一位的答案呢?一位的范围并不大,直接枚举即可。在压位的情况里(比如每位为1e9),可以在0到1e9之间二分答案。而这样也是符合实际计算的。试想一下,手算100/13时,心里想的也是“13x7=91小了,13x8过一百了,答案是7”,其本质就是二分。

另外,我们知道x位数乘以y位数只能是x+y位数或者x+y-1位,所以x位数除以y位数,最多只有x-y+1位数,从第x-y+1开始枚举即可。

int lans;
struct DecInt {
int len, a[MAX];
void trim() {
while (len && !a[len-1]) --len;
}
DecInt operator*(int x) const {
//高精乘低精
DecInt ans = DecInt(len);
long long num = 0;
for (register int i = 0; i < len; i++) {
num += (long long)a[i] * x;
ans.a[i] = num % MOD;
num /= MOD;
}
if (num) ans.a[ans.len++] = num;
return ans.trim(), ans;
}
DecInt& operator-=(const DecInt &x) {
//这里的自减需要将被减数移动lans位后相减
for (int i = 0; i < x.len; i++) {
a[i + lans] -= x.a[i];
if (a[i + lans] < 0)
a[i + lans] += MOD, a[i + lans + 1]--;
}
for (int i = x.len + lans; i < len; i++)
a[i] < 0 && (a[i] += MOD, a[i+1]--);
return trim(), *this;
}
bool comp(const DecInt &t, const DecInt &divd) {
//这里的比较是比较答案和除数的积和被除数,需要将被除数移动ans位
if (t.len != divd.len - lans) return t.len < divd.len - lans;
for (int i = t.len-1; ~i; i--)
if (t.a[i] != divd.a[i+lans]) return t.a[i] < divd.a[i+lans];
return 1;
}
DecInt operator/(const DecInt &B) {
lans = len - B.len;
if (lans < 0)
return DecInt("0", 1);
DecInt ans = DecInt(lans + 1);
while (~lans) {//从第lans位开始计算答案
int l = 0, r = MOD-1;
while (l < r) {
//二分求解第lans位
int mid = l + r + 1 >> 1;
comp(B * mid, *this) ? l = mid : r = mid-1;
}
*this -= B * l;//将被除数减掉本位答案和除数的积
ans.a[lans--] = l;
}
return ans.trim(), ans;
}
};

可以看到,每次只取的被除数去掉后面lans位的数来进行操作(比如上例里,第一次除时只比较"435",做减法时也是从"435"开始操作),提高的效率。

另外就是二分答案不能写错,乘积小了增大l,乘积大了减小r,而正好相等时,mid也有可能是答案,不能被排掉。

.NET Core 中如何实现缓存的预热? 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异 AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现 基于Microsoft.Extensions.AI核心库实现RAG应用 Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗? 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统 【译】Visual Studio 中新的强大生产力特性 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示