C 按2的倍数进行位除法

C 按2的倍数进行位除法,c,bit-manipulation,C,Bit Manipulation,我找到了很多关于按位除法的帖子,我完全理解大多数按位除法的用法,但我想不出具体的除法。我想把一个给定的数字(比如说100)除以所有可能的2的倍数(注意:我不想除以2位倍数的幂!) 例如:100/2100/4100/6100/8100/10…100/100 我还知道,由于使用了unsigned int,答案将四舍五入,例如100/52=0,但这并不重要,因为我可以跳过这些答案或打印它们,没有问题。我关心的主要是如何用6或10除,等等(2的倍数)。这需要用C来完成,因为我可以设法将您给我的任何代码从

我找到了很多关于按位除法的帖子,我完全理解大多数按位除法的用法,但我想不出具体的除法。我想把一个给定的数字(比如说100)除以所有可能的2的倍数(注意:我不想除以2位倍数的幂!)
例如:100/2100/4100/6100/8100/10…100/100

我还知道,由于使用了
unsigned int
,答案将四舍五入,例如100/52=0,但这并不重要,因为我可以跳过这些答案或打印它们,没有问题。我关心的主要是如何用6或10除,等等(2的倍数)。这需要用C来完成,因为我可以设法将您给我的任何代码从Java转换为C。

尽可能多地使用运算符
/
进行整数除法

例如,当您想将100除以6或10时,您应该编写
100/6
100/10
。 当您提到位除法时,您(1)是指运算符
/
的实现还是(2)您指的是二次幂除法

对于(1),处理器应具有整数除法单元。如果没有,编译器应该提供一个良好的实现


对于(2),您可以使用
100>>2
而不是
100/4
。如果分子在编译时已知,那么一个好的编译器应该自动使用shift指令。

根据为的可接受解显示的数学,您可以推导除法算法的递归:

计算
(int)
(X/Y)

  • 设k为2k≥Y和2k-1 (注意,2k=
    (10)返回divu(x,y);
    返回否定(divu(x,否定(y));
    }
    

    此实现依赖于使用2的补码的
    有符号int
    。为了最大的可移植性,
    div
    应该在调用
    divu
    之前将负参数转换为2的补码。然后,它应该将
    divu
    的结果从2的补码转换回本机有符号表示。

    下面的code适用于正数。当被除数或除数或两者均为负数时,使用标志适当更改答案的符号

    int divi(long long m, long long n)
    {
        if(m==0 || n==0 || m<n)
            return 0;
        long long  a,b;
        int f=0;
        a=n;b=1;
    
        while(a<=m)
        {
            b = b<<1;
            a = a<<1;
            f=1;
        }
    
        if(f)
        {
            b = b>>1;
            a = a>>1;
        }
    
        b = b + divi(m-a,n);
        return b;
    }
    
    int divi(长m,长n)
    {
    
    如果(m==0 | | n==0 | |许多迹象表明你为什么要进行位运算而不是简单地使用除法?这与将数字除以2,然后将结果除以每个可能的整数是一样的。你不能除以2的倍数,只能除以2的幂,至少不容易。我知道这不是dasblink,因为对你来说,Vaugh我的朋友除以2只是右移1位除以4是2位除以8是3位向右移动,但是除以6呢?…我的朋友霍华德,我想这样做是因为我必须为大学做这件事…我想知道老师的要求是不是失败了,或者是否有可能做到,以及如何…结帐:
    X/Y = A + (d * A + B)/Y
    
    static unsigned divu (unsigned x, unsigned y) {
        unsigned k = 0;
        unsigned pow2 = 0;
        unsigned mask = 0;
        unsigned diff = 0;
        unsigned sum = 0;
        while ((1 << k) < y) k = add(k, 1);
        pow2 = (1 << k);
        mask = sub(pow2, 1);
        diff = sub(pow2, y);
        while (x >= pow2) {
            sum = add(sum, rs(x, k));
            x = add(mul(diff, rs(x, k)), (x & mask));
        }
        if (x >= y) sum = add(sum, 1);
        return sum;
    }
    
    int div (int x, int y) {
        assert(y);
        if (y > 0) return divu(x, y);
        return negate(divu(x, negate(y)));
    }
    
    int divi(long long m, long long n)
    {
        if(m==0 || n==0 || m<n)
            return 0;
        long long  a,b;
        int f=0;
        a=n;b=1;
    
        while(a<=m)
        {
            b = b<<1;
            a = a<<1;
            f=1;
        }
    
        if(f)
        {
            b = b>>1;
            a = a>>1;
        }
    
        b = b + divi(m-a,n);
        return b;
    }