DataLab详解

水平有限欢迎讨论

有些函数里面定义变量要提前在函数的第一行定义完的,不然编译的时候会报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;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值