[英]64 bit / 64 bit remainder finding algorithm on a 32 bit processor?
我知道过去也曾问过类似的问题,但是经过很长的过程,我已经实现了使用重复减法除法来正确找到商的算法。 但是我无法从这种方法中找到其余的内容 。 是否有任何快速简便的方法来找出32位处理器上64位/ 64位除法中的余数 。 更确切地说,我正在尝试实施
ulldiv_t __aeabi_uldivmod(
unsigned long long n, unsigned long long d)
本文档中引用了http://infocenter.arm.com/help/topic/com.arm.doc.ihi0043d/IHI0043D_rtabi.pdf
什么? 如果您重复进行减法运算(听起来确实很基础),那么剩下的难道就不是像您不能再进行一次减法运算时所剩下的一样简单吗?
至少这是幼稚的直观方式:
uint64_t simple_divmod(uint64_t n, uint64_t d)
{
if (n == 0 || d == 0)
return 0;
uint64_t q = 0;
while (n >= d)
{
++q;
n -= d;
}
return n;
}
还是我想念小船,在这里?
当然,对于大量用户而言,这将非常慢,但这是重复的减法。 我敢肯定(甚至不看!)还有更高级的算法。
这是一个除法算法,以O(log(n / d))运行
uint64_t slow_division(uint64_t n, uint64_t d)
{
uint64_t i = d;
uint64_t q = 0;
uint64_t r = n;
while (n > i && (i >> 63) == 0) i <<= 1;
while (i >= d) {
q <<= 1;
if (r >= i) { r -= i; q += 1; }
i >>= 1;
}
// quotient is q, remainder is r
return q; // return r
}
如果仅需要r(余数),则可以删除q(商)。 您可以将每个中间变量i,q,r实现为一对uint32_t,例如i_lo,i_hi,q_lo,q_hi ..... shift,加法和减法lo和hi是简单的操作。
#define left_shift1 (a_hi, a_lo) // a <<= 1
{
a_hi = (a_hi << 1) | (a_lo >> 31)
a_lo = (a_lo << 1)
}
#define subtraction (a_hi, a_lo, b_hi, b_lo) // a-= b
{
uint32_t t = a_lo
a_lo -= b_lo
t = (a_lo > t) // borrow
a_hi -= b_hi + t
}
#define right_shift63 (a_hi, a_lo) // a >> 63
{
a_lo = a_hi >> 31;
a_hi = 0;
}
等等。
除数0仍未解决:-)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.