基于uint64_t的任意精度实数快速长除法算法优化咨询
我正在开展一个科学计算项目,需要实现任意实数的任意精度运算。目前采用两个uint64_t动态数组表示实数近似值:一个数组存储整数部分的数字块,另一个存储小数部分,每个uint64_t对应一个64位数字块,计算更多小数位时直接将新块追加到数组末尾。
我一直在寻找可利用C++硬件加速的/和%运算符实现的快速长除法算法。
先从p/q场景入手:p、q均为uint64_t,且p<q(即该有理数小于1),同时p、q均小于264。我的思路是采用基数为264的数制,将欧几里得算法的每一步视为原子操作,用/和%完成计算。该算法需返回前64位十进制数字(此场景小数点左侧无有效数字),以及余数(同样为uint64_t,因余数小于分母且分母<2^64)。
但推导后发现:在基数为b的数制中做长除法,必须能对小于b²的数执行除法。例如十进制下计算13/5,需直接对13做除法:
2 _____ // 5无法整除1或3,因此必须能直接对13做除法 5 | 1 3
暴力长除法是可行方案,但会产生大量控制流分支,我认为存在能大幅减少分支的巧妙实现方式。
我尝试过一个直接优化:用快速Log2函数确定uint64_t的最高有效位位置,执行欧几里得算法时跳过零块以提升性能,但最坏情况下仍需对每一位执行一次除法。
将块大小改为uint32_t也无法解决问题:虽可将分子中两个uint32_t拼接为uint64_t,分母扩展为uint64_t后用硬件/和%一次性完成除法,但遇到余数较大的场景(如最高有效位在2^60位置)时,仍需扫描三个数字再执行除法,还要进行移位和掩码操作适配寄存器。
我的疑问是:当前方案已是最优解吗?现有方法在/和%调用次数上本质为O(n),我未找到分治法或带进位智能算术的应用途径,故寻求更优实现方案。
内容的提问来源于stack exchange,提问作者BENG

