C 按2的倍数进行位除法
我找到了很多关于按位除法的帖子,我完全理解大多数按位除法的用法,但我想不出具体的除法。我想把一个给定的数字(比如说100)除以所有可能的2的倍数(注意:我不想除以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/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
之前将负参数转换为2的补码。然后,它应该将divu
的结果从2的补码转换回本机有符号表示。下面的code适用于正数。当被除数或除数或两者均为负数时,使用标志适当更改答案的符号divu
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; }