在o(1)中实现c二进制除法

时间:2015-04-28 00:11:02

标签: c binary division

我找到了这个(略微修改过的)代码来实现对无符号数的除法:

#include <climits>
#include <stdio.h>



unsigned divide(unsigned dividend, unsigned divisor) { 


    unsigned current = 1;
    unsigned answer=0;

    if ( divisor > dividend) 
        return 0;

    if ( divisor == dividend)
        return 1;

    while (divisor <= dividend) {   // this will not work with UINT_MAX
        divisor <<= 1;
        current <<= 1;
    }

    divisor >>= 1;
    current >>= 1;

    while (current!=0) {
        if ( dividend >= divisor) {
            dividend -= divisor;
            answer |= current;
        }
        current >>= 1;
        divisor >>= 1;
    }    
    return answer;
}
int main()
{
    unsigned int x =0;
    x = divide (UINT_MAX,113);
    printf ("%u",x);

    return 0;
}

它与#34;正常&#34;非常适用值,但除了max unsigned int值会产生问题;因为它的Oxffffffff不可能移动 divisor 足以使其变大 - 任何进一步的移位都会将除数推到32位限制并破坏该值,从而产生无限循环。我可以获得有关如何解决此错误的建议吗?甚至可能创建一个硬代码案例?

2 个答案:

答案 0 :(得分:0)

而不是

while (divisor <= dividend) {   // this will not work with UINT_MAX
    divisor <<= 1;
    current <<= 1;
}

divisor >>= 1;
current >>= 1;

unsigned k = 1 << (sizeof(unsigned) * 8 - 1);
while (((divisor & k) == 0) && ((divisor << 1) <= dividend)) {
    divisor <<= 1;
    current <<= 1;
}

我们的想法是,在建议的算法中,divisorcurrent的最后一个左移由稍后的右移补偿。所以我们可以在第一时间避开它。

答案 1 :(得分:0)

另一种解决方案可能是使用无符号长整数。