1.异或:
int bitXor(int x, int y) {
int val1 = (~x)&y;
int val2 = (~y)&x;
return ~((~val1)&(~val2));
}
思路的关键在于将两数x,y各自机器级01序列中同一位置上不同的地方记录下来
分为4种情况:
y | … | 1 | … | 1 | … | 0 | … | 0 |
---|---|---|---|---|---|---|---|---|
x | … | 1 | … | 0 | … | 1 | … | 0 |
首先将表中第2,3列分别以1的方式记录下来即代码第一二行
但是由于不能直接使用加法和位级或运算,所以,这是只需要将上一操作得到的两个01序列各位取反(~)再相与,最后再做一次取反即可
2.判断奇数位是否均为1:
int allOddBits(int x) {
int val1=3*x+1;
return !x;
}
0 | 1 | 0 | 1 | … | 0 | 1 | 0 | 1 |
---|
显然,只需满足1个条件即可:2x+x得到的是一个全1序列(直接x*3即可)
如果满足要求条件则第一步就得到了一个全1序列,再将之加上1则为全0序列(即值为0)
再进行非运算(!)就得到了1
如果不满足则第一步就得不到全1序列,加上1也就不会是全0序列,再通过!运算返回0
这里还有另一种方法:将2x进行~运算,再与x异或,将最终得到的结果进行非运算(!)返回:
int allOddBits(int x) {
int val1=(2*x)^x;
return !val2;
}
``
3.判断是否为ASCII码值
int isAsciiDigit(int x) {
int val1 = x+6;//上限
int val2 = !(val1>>6);//val2的值为1表示小于0x39,为0表示大于0x39或者为负数
int val3 = (x-16)>>5;//如果x小于0x30,那么x-16从低有效位开始的第6为必定为0
int val4 = 1&val3;
int val5 = val2&val4;
}
4.条件返回:
int conditional(int x, int y, int z) {
int val1 = ~(y&(~z));//将Y为1而Z为0的地方以0的方式记录下来
int val2 = (~y)&z;//将Y为0而Z为1的地方以1的方式记录下来
return y&((x&val1)|(~x&val1)) + (((~~(!x))>>1)&val2);
// 根据x将y1z0 根据x将y0z1
// 的地方更改 的地方更改
}
5.How Many Bits
提供一个参数返回用二进制补码表示它所需的最小位数
合法运算符:! ~ & | ^ + << >>
Max ops:90
int HowmanyBits(int x){
int value=x^(x<<1);
int count = 1 + (!!(value>>16)<<4);
int next = value>>(!!(value>>16)<<4);
count = count + (!!(value>>8)<<3);
next = next>>(!!(next>>8)<<3);//条件左移,确定下一个操作数
count = count + (!!(value>>4)<<2);
next = next>>(!!(next>>4)<<2);
count = count + (!!(value>>2)<<1);
next = next>>(!!(next>>2)<<1);
count = count + (value>>1)
}
思路先对x进行处理,即将x左移一位的结果与x异或这样的到的结果从左至右,第一位非0值的位置即表示了最少需要的位数
再运用折半的方法定位目标数值,即分别左移16,8,4,2,1位
6.非运算(利用除了"!“以外的其他合法运算符实现”!",即x为0时返回1,x为非0时返回0)
int LogicalNeg(int x){
int value = ~((x^(~x+1))|(x&(~x+1)));
return 1&(value>>31);
}
思路:考虑求非0的x的二进制补码再位级上面的行为是从右至左第一个非0数(即1)的后一位开始各位取反,那么x与其补码进行异或运算(^)就会生成一个左边是i个连续1(0<=i<=31)右边连续(32-i)个0的01序列,示意图如下:
1111 | … | 111000 | … | 00 |
---|
而如果是0的做(0^(~0+1))话就会得到全0序列,利用这个区别,可以将得到的结果各位取反后左移31位,再析取最低位即可。
但是除此之外还要考虑一个特殊情况:0x80000000,它做x^(~x+1)之后得到的也是全0序列。故此在进行处理得到value的时候多增加了一步与(x& ( ~x+1))的或运算。
浮点数部分
1.float - Return bit-level equivalent ofexpression 2*f for floating point arguement f //返回unsinged表示的浮点数的两倍
Legal ops:Any integer/unsinged operations incl. || , &&also if ,while
Max ops:30
代码如下:
unsigned floatScale2(unsigned uf) {
int SF = (1&(uf>>31))<<31;//符号位
int exp = (uf>>23)&((1<<8)-1);//阶码
int e23 = ((1<<23)-1);//23个1
int EM = e23&uf;//尾数
int if8exp = 1&((exp+1)>>8);//判断exp是否全1
if(!(EM|exp)||if8exp)return uf;//0,NaN,无穷大的情况下返回自身
if(!exp){//阶码全0
EM = (EM<<1)&e23;
if(1&(EM>>22)){//尾数最高位为1
exp = exp + 1;
}
exp = exp<<23;
}
else{
exp = exp+1;
if(if8exp){//加1后阶码溢出,返回无穷大
EM=0;
}
}
return SF|exp|EM;
}
2.floatFloat2Int - Return bit-level equivalent of expression (int) f for floating point argument f. //实现(int)f
Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
Max ops:30
代码如下:
int floatFloat2Int(unsigned uf) {
int SF = 1&(uf>>31);
int e8 = (1<<8)-1;
int e23 = (1<<23)-1;
int exp = (uf>>23)&e8;
int M = uf&e23;
if((exp+1)>>8)return exp<<23;//如果exp为全1
int final=0;
if(exp){//规格化数,对隐藏的“1”进行处理
final=final+(1<<exp);
}
int i = 23;
while(M){//循环各位尾数乘以阶码,求和
final = final + (M&1)<<(exp-i);
i--;
M=M>>1;
}
if(SF)final = ~final+1;//如果uf为负数
return final;
}
3.floatPower2 - Return bit-level equivalent of the expression 2.0^x(2.0 raised to the power x)for any 32-bit integer x. //将浮点数表示的2的x次幂转化为int型
Legal ops:Any integer /unsigned operations incl. || && Also if while
Max ops:30
unsigned floatPower2(int x){
int high = 1&((x-129)>>31);//x-129应该小于0
int low1 = 1&((x+126)>>31);//对于规格化数x+126应该大于或等于0
int low2 = !(1&((x+149)>>31));//对于如何包括非规格化数,x+129都应该大于或等于0
if(!high)return ((1<<8)-1)<<23;//大于上限(并非最大规格化数)
if(high&&(!low1))return (x+127)<<23;//处于规格化数区间
if(low1&&low2)return 1<<(x+149);//处于规格化数区间
return 0;//小于最小规格化数
}
其他实验较为简单,所以只贴出代码供参考,不作解释
tmin - return minimun tow’s complement integer//返回最小二进制补码
Legal ops:!~&^|+<<>>
Max ops :4
int tmin(void){
return 1<<31;
}
isTmax - returns 1 if x is the maximun,tow’s complement number,and 0 otherwise
Legal ops!~&^|+
Max ops:10
int isTmax(int x){
return !(~x+x+1);
}
negate - return -x
Legal ops:! ~ & ^ | << >> +
Max ops:5
int negate(int x){
return (~x+1);
}
isLessOrEqual - if x<=y then return 1 ,else return 0
Legal ops:! ~ & ^ | + << >>
Max ops:24
int isLessOrEqual(int x,int y){
int value1 = (((~y)&x)>>31)&1;//y为正而x为负
int value2 = (~((y+(~x+1))>>31))&1;//y减去x符号位为0
return value1|value2;
}