水平有限欢迎讨论
有些函数里面定义变量要提前在函数的第一行定义完的,不然编译的时候会报parse error的错误
一些要点:
1.可以用x^y判断两数是否相等。但是如果要返回结果变成0/1还是需要关键的!(非)。
2.实现if或者三目运算符。两种方法,但是主要思路是把正数变成1然后取反成-1就是0xffffffff 再和另一边~的用|结合来实现。
int conditional(int x, int y, int z) {
x=!!x;
x=~x+1; //转换为全0或全1
return (x&y) | (~x&z);
}
int conditional(int x, int y, int z) {
int op=~1+1;
( (!x+op)&y ) | ( (!!x+op)&z);
}
3.关于取符号位
>>31后应不应该&1根据实际情况。如果需要用于变成if条件,则不要&,因为需要全1;无需的在指令够的情况下可以&上防止其他情况。
4.判断AsciiDigit
由于只判断处于一个范围内。可以考虑用减法的判断来代替。确实x-y<0不可靠,因为会溢出,但是在此种情况下就算溢出不会使得<=0x39的条件成立,所以是安全的。
5.位运算实现!
对于!的定义:!0=1;其余皆为0
观察0的补码+1后|0符号位仍然是0;而其他数符号位都是1;于是>>31再+1看是1还是0xffffffff--->0
6.对于判断所有奇数位的方法,我刚刚好用完所有操作数。思路是每8位一个块,然后对块内处理然后再移8位,类似分块处理。刚好用完。
7.对于howManyBits,思路是类似二分。先以中间为界,判断高16位是否满足,满足就加上低16位的16,然后移位16位,变成一个新的16位块。如果不满足,说明mid要往右边移到第8位的位置。此时不移位。之后重复刚才的动作。
int bitXor(int x, int y) {
int a=~x&y;
int aa=~a;
int b=x&~y;
int bb=~b;
int c=aa&bb;
int ans=~c;
return ans;
}
int tmin(void) {
return (1<<31);
}
int isTmax(int x) {
return (!(x+1+x+1)&!!(x+1));
}
int allOddBits(int x) {
int a,b,c,d;
a=(x&0xAA);
x=(x>>8);
b=(x&0xAA);
x=x>>8;
c=(x&0xAA);
x=x>>8;
d=(x&0xAA);
return !( (0XAA)^(a&b&c&d) );
}
int negate(int x) {
return ~x+1;
}
int isAsciiDigit(int x) {
int a=~48+1;
int b=~58+1;
return ( !( (x+a)>>31) )&( !!((x+b)>>31) );
}
int conditional(int x, int y, int z) {
int op=~1+1;
return ( (!x+op)&y ) | ( (!!x+op)&z);
}
int isLessOrEqual(int x, int y) {
int highx=1&(x>>31);
int highy=1&(y>>31);
int res=highx^highy;
//同号
int yy=~y+1;
int cnt=x+yy;
int op=1&(cnt>>31);
//异号
int check= (res&highx)|( (!res)& ( op ) )|(!(x^y));
check=~check+1;
return (check&1)|(~check&0);
}
int logicalNeg(int x) {
return ( ( x|(~x+1) )>>31)+1;
}
///二分
int howManyBits(int x) {
//正数找最高位的1再加符号位(负数取反后就是也找这个最高位的1)
int b16,b8,b4,b2,b1,b0;///变量提前都声明出来,频繁int b16=表达式会parse error
int op=x>>31;///获得全1,用于if条件的不能&1
x=(op&~x)|(~op&x);//负数取反正数不变
b16=!!(x>>16)<<4;//如果高16位有1那么右边的低16位的数量全部需要累加
x=x>>b16;
b8=!!(x>>8)<<3;
x=x>>b8;
b4=!!(x>>4)<<2;
x=x>>b4;
b2=!!(x>>2)<<1;
x=x>>b2;
b1=!!(x>>1);
x=x>>b1;
b0=x;
return b16+b8+b4+b2+b1+b0+1;
}
unsigned floatScale2(unsigned uf) {
/*存储方式 s exp frac (s:符号位 E=exp-bias)
*v = (-1)^s * M * 2^E (0<M<2)
* */
unsigned exp=(uf&0x7f800000)>>23;
unsigned op=(1<<31)&(uf);
if(exp==0) return (uf<<1)|op;
if(exp==255) return uf;
exp++;
if(exp==255) return (0x7f800000)|op;
return op|(exp<<23)|(uf&0x007fffff);
}
int floatFloat2Int(unsigned uf) {
unsigned sigh=1&(uf>>31);
unsigned exp=( (uf&(0x7f800000) )>>23);
unsigned frac=(uf&(0x007fffff))|(0x00800000);///取出frac,将小数部分变为整数,补上默认的最高位1(尾数部分自带的)
int E=exp-0x7f;
if(E>31) return 0x80000000;
if(E<0) return 0;
if(E>23) frac=(frac<<(E-23));
else frac=(frac>>(23-E));
if(!sigh) return frac;
if(sigh) return ~frac+1;
}
unsigned floatPower2(int x) {
int INF=0Xff<<23;
int exp=x+127;
if(exp>=255) return INF;
if(exp<0) return 0;
return exp<<23;
}