bitAnd
可用运算符:~ |
x&y得到x,y相同位置的1,~x | ~y,得到~x,~y相同位置的0,~(~x | ~y)=x&y |
int bitAnd(int x, int y)
{
return ~(~x | ~y);
}
getByte
可用运算符:! ~ & ^ | + « » |
x右移n个字节&0xFF,移动n个字节就是移动n*8位,n*8就是n左移3位
int getByte(int x, int n)
{
return (x >> (n << 3)) & 0xFF;
}
logicalShift
可用运算符: ! ~ & ^ | + « » |
先算术右移,再&0….01….1(n个0)
构造0….01….1
1左移31位再按位取反得到10….0(31个0),按位取反再右移n位得到0…01…1(n+1)个0,左移一位得到0..01..10(前面n个0),末尾加1,得到0….01….1(n个0)
int logicalShift(int x, int n)
{
return (x >> n) & ((~(1 << 31) >> n << 1) + 1);
}
bitCount
可用运算符: ! ~ & ^ | + « » |
bang
可用运算符:~ & ^ | + « » |
正数取相反数,除符号位之外按位取反,然后加1,得到负数的补码。
0和-0的补码相同,0 | -0 符号位为0,其余正数 | 相反数符号位为1 |
计算x | -x,右移31位,若x不为0则得到0xFFFFFFFF,若x为0则得到0x0,加一得到!x |
int bang(int x)
{
return (((x | (~x + 1)) >> 31) + 1);
}
tmin
可用运算符:! ~ & ^ | + « » |
-2147483648
int tmin(void)
{
return (1<<31);
}
fitsBits
可用运算符:! ~ & ^ | + « » |
对于正数若能表示则第32位到第n位全为0
对于负数若能表示则第32位到第n位全是1
所以若能表示则x先左移32-n位再右移32-n位一定与x相同
int fitsBits(int x, int n)
{
int a;
a=32+(~n+1);
return !(((x<<a)>>a)^x);
}
divpwr2
可用运算符:! ~ & ^ | + « » |
正数直接右移n位,但负数这样搞就向下取整了
如果是负数应该加上2^n-1再右移
int divpwr2(int x, int n)
{
return (x + ((x >> 31) & ((1 << n) + ~0))) >> n;
}
negate
可用运算符:! ~ & ^ | + « » |
(~x)+1
int negate(int x)
{
return ((~x) + 1 );
}
isPositive
可用运算符:! ~ & ^ | + « » |
判断是否为0或负数
int isPositive(int x)
{
return !(!x | (x >> 31));
}
isLessOrEqual
可用运算符:! ~ & ^ | + « » |
y-x>=0,如果x,y异号可能会溢出,所以两种情况。x,y异号,根据x正负判断,x,y同号,根据y-x判断
int isLessOrEqual(int x, int y)
{
int xx;
int yy;
int flag;
int diff;
xx = (x >> 31) & 1;
yy = (y >> 31) & 1;
flag = xx ^ yy;
diff = ((y + (~x + 1)) >> 31) & 1;
return (flag & xx) | (!diff & !flag);
}
可用运算符:! ~ & ^ | + « » |
float_neg
如果是NaN,一定大于0x7F800000
unsigned float_neg(unsigned uf)
{
unsigned res;
res = uf ^ 0x80000000;
if( (uf & 0x7FFFFFFF;) > 0x7F800000)
return uf;
return res;
}
float_i2f
unsigned float_i2f(int x)
{
unsigned shiftLeft=0;
unsigned afterShift, tmp, flag;
unsigned absX=x;
unsigned sign=0;
if (x == 0)
return 0;
if (x < 0)
{
sign = 0x80000000;
absX = -x;
}
afterShift = absX;
while (1)
{
tmp=afterShift;
afterShift <<= 1;
shiftLeft++;
if (tmp & 0x80000000) break;
}
if ((afterShift & 0x01ff)>0x0100)
flag = 1;
else if ((afterShift & 0x03ff)==0x0300)
flag = 1;
else
flag = 0;
return sign + (afterShift>>9) + ((159-shiftLeft)<<23) + flag;
}
unsigned float_twice(unsigned uf)
{
unsigned f = uf;
if ((f & 0x7F800000) == 0)
{
f = ((f & 0x007FFFFF) << 1) | (0x80000000 & f);
}
else if ((f & 0x7F800000) != 0x7F800000)
{
f = f + 0x00800000;
}
return f;
}
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议(CC BY-NC-ND 4.0)进行许可。
This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License (CC BY-NC-ND 4.0).