本博客参考了链接https://blog.csdn.net/qq_42792383/article/details/86824293
特在此鸣谢。
以下为datalab的部分解析:
//1
/*
* bitXor - x^y using only ~ and &
* Example: bitXor(4, 5) = 1
* Legal ops: ~ &
* Max ops: 14
* Rating: 1
*/
int bitXor(int x, int y) //只用&和~实现^
{
return (~(~x&~y))&(~(x&y));/*主要应用了摩尔根定律,
(~(~x&~y))==(x|y),即x或y,(~(~x&~y))&(~(x&y))即x或y并且排除掉x与y同时为真的情况,即异或*/
}
/*
* tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 1
*/
int tmin(void) //求最小的补码
{
return 1<<31;
}
//2
/*
* isTmax - returns 1 if x is the maximum, two's complement number,
* and 0 otherwise
* Legal ops: ! ~ & ^ | +
* Max ops: 10
* Rating: 1
*/
int isTmax(int x)//如果x是最大值返回1,否则返回0
{
return 2;
}
/*
* allOddBits - return 1 if all odd-numbered bits in word set to 1
* where bits are numbered from 0 (least significant) to 31 (most significant)
* Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 12
* Rating: 2
*/
int allOddBits(int x)//如果x奇数位全为1,返回1;否则返回0
{
return !(~x&0xaaaaaaaa);
/*0xaaaaaaaa的偶数位全为0,奇数位全为1。
当x满足奇数位全为1时,~x&0xaaaaaaaa的奇数位全为0,偶数位也全为0,!(~x&0xaaaaaaaa)等于1;
当x不满足奇数位全为1时,~x的奇数位必有为1的,~x&0xaaaaaaaa不为0,!(~x&0xaaaaaaaa)等于0*/
}
/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x) //求-x
{
return ~x+1;
}
//3
/*
* isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')
* Example: isAsciiDigit(0x35) = 1.
* isAsciiDigit(0x3a) = 0.
* isAsciiDigit(0x05) = 0.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 15
* Rating: 3
*/
int isAsciiDigit(int x)//如果x在0x30到0x39之间返回1;否则返回0
{
/*0x30到0x39的数x满足,x-0x30的符号位为0,x-0x3a的符号位为1*/
return (!((x+(~(0x30)+1))>>31))&((x+(~(0x3a)+1))>>31);
/*(x+(~(0x30)+1)表示x-0x30;
(!((x+(~(0x30)+1))>>31))表示取x-0x30的符号位再取反;((x+(~(0x3a)+1))表示x-0x3a;
((x+(~(0x3a)+1))>>31)表示取x-0x3a的符号位;(!((x+(~(0x30)+1))>>31))&((x+(~(0x3a)+1))>>31)
表示只有当x-0x30的符号位为0且x-0x3a的符号位为1时返回1;*/
}
/*
* conditional - same as x ? y : z
* Example: conditional(2,4,5) = 4
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 16
* Rating: 3
*/
int conditional(int x, int y, int z)//x为0返回z;否则返回y
{
int mask;
mask=!x+~1+1;
return (mask&y)|(~mask&z);
/*!x+~1+1相当于!x-1;当x不为0时,!x-1等于-1,而-1的补码为0xffffffff,
0xffffffff&y等于y,~0xffffffff等于0,0&z等于0,y|0等于y;
当x为0时,!x-1等于0,0&y等于0,~0等于0xffffffff,0xffffffff&z等于z,0|z等于z*/
}
/*
* isLessOrEqual - if x <= y then return 1, else return 0
* Example: isLessOrEqual(4,5) = 1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 24
* Rating: 3
*/
int isLessOrEqual(int x, int y) //x<=y返回1,否则返回0
{
return ((((x+~y+1)>>31)&0x1)|!(x^y)|((x>>31)&0x1)&!((y>>31)&0x1))
&!(!((x>>31)&0x1)&((y>>31)&0x1));
/*x+~y+1等于x-y;
当x<y时,(x+~y+1)>>31等于0xffffffff,0xffffffff&0x1等于0x1;
!(x^y)等于0x0,0x1|0x0等于1;当x=y时,(x+~y+1)>>31等于0x0,0x0&0x1等于0x0,
!(x^y)等于0x1,0x0|0x1等于1;当x>y时,(x+~y+1)>>31等于0x0,0x0&0x1等于0x0,
!(x^y)等于0x0,0x0|0x0等于0*/
//后面的操作考虑了两种溢出情况,当x为负数y为正数返回1,当x为正数y为负数返回0
}
//4
/*
* logicalNeg - implement the ! operator, using all of
* the legal operators except !
* Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
* Legal ops: ~ & ^ | + << >>
* Max ops: 12
* Rating: 4
*/
int logicalNeg(int x) //不用!的条件下实现!运算
{
return ((~x&~(~x+1))>>31)&1;
/*-x=~x+1,当x取0时,计算机中x与-x符号位均为0,
x=TMin时,x与-x符号位均为1;其它情况下,x与-x符号位必然不同。所以,(~x&~(~x+1))
只有当x等于0时符号位为1,即((~x&~(~x+1))>>31)&1等于1,其余情况返回0*/
}
/* howManyBits - return the minimum number of bits required to represent x in
* two's complement
* Examples: howManyBits(12) = 5
* howManyBits(298) = 10
* howManyBits(-5) = 4
* howManyBits(0) = 1
* howManyBits(-1) = 1
* howManyBits(0x80000000) = 32
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 90
* Rating: 4
*/
int howManyBits(int x) //求表示x至少需要几位
{
return 2;
}
//float
/*
* floatScale2 - Return bit-level equivalent of expression 2*f for
* floating point argument f.
* Both the argument and result are passed as unsigned int's, but
* they are to be interpreted as the bit-level representation of
* single-precision floating point values.
* When argument is NaN, return argument
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
unsigned floatScale2(unsigned uf)//将无符号整型当作浮点数,实现2.0*uf
{
unsigned s = uf&0x80000000;//记录符号位,其余位置0
unsigned exp = uf&0x7f800000;//记录阶码,其余位置0
unsigned frac = uf&0x007fffff;//记录尾数,其余位置0
if(!exp) //如果uf的阶码为0
{
frac<<=1;
/*将frac左移一位,若尾数部分第一位为0,左移前后均为非规格化数,
尾数左移一位就相当于乘2;若尾数部分第一位为1,左移前为非规格化数,
左移后阶码部分由00000000变为00000001,阶码由1-127=-126(1-Bias)
变为e-127=1-127=-126(e-Bias),所得数为规格化数,尾数被解释为1+f,
相当于尾数乘2,阶码不变*/
}
else if(exp^0x7f800000) //如果阶码部分不为全1
{
exp += 0x00800000;//阶码加1,对于规格化数,相当于乘2
if(!(exp^0x7f800000))//如果加1后,阶码为全1,将尾数位全置0,返回值即是无穷大
{
frac = 0;
}
}
/*对于阶码为在本身为全1的NaN,本函数没有对其进行操作,返回原数据,满足关卡要求*/
return s|exp|frac;//将符号位,阶码位,尾数位通过按位异或结合起来
}
/*
* floatFloat2Int - Return bit-level equivalent of expression (int) f
* for floating point argument f.
* Argument is passed as unsigned int, but
* it is to be interpreted as the bit-level representation of a
* single-precision floating point value.
* Anything out of range (including NaN and infinity) should return
* 0x80000000u.
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
int floatFloat2Int(unsigned uf)//将无符号整型当作浮点数,实现(int)uf
{
return 2;
}
/*
* floatPower2 - Return bit-level equivalent of the expression 2.0^x
* (2.0 raised to the power x) for any 32-bit integer x.
*
* The unsigned value that is returned should have the identical bit
* representation as the single-precision floating-point number 2.0^x.
* If the result is too small to be represented as a denorm, return
* 0. If too large, return +INF.
*
* Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while
* Max ops: 30
* Rating: 4
*/
unsigned floatPower2(int x) //将整型当作浮点数,实现2.0^x
{
return 2;
}
#以下为运行结果
#datalab让我们深入位级去思考问题,本实验需要用到许多巧妙的办法与技巧去实现
看似简单却令人无从下手的问题。关注符号位,关注溢出情况,关注补码最小值......
最终还是归结于关注数据如何在计算机中存储以及如何进行运算。