环境配置
- 安装gcc库
yum install glibc-devel.i686
- 报错,在vs中安装c/c++拓展
- 再次安装,成功
函数实现
bitXor
/*
* bitXor - x^y using only ~ and &
* Example: bitXor(4, 5) = 1
* Legal ops: ~ &
* Max ops: 14
* Rating: 1
*/
int bitXor(int x, int y) {
//x^y=(~x&y)|(x&~y)
//=~(~(~x&y)&~(x&~y))
//4=1000,5=1001,德摩根定律
return ~(~(~x&y)&~(x&~y));
}
tmin
/*
* tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 1
*/
int tmin(void) {
//返回最小补码值 0x8000 0000
return 1<<31;
}
ifTmax
/*
* 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)
{
//判断是否是最大补码 最大补码为0x7fffffff
//按位异或,取非,全0输出1
int y = x+1;
y=x+y;
y=~y;
y=!y;
return y&!!(~x);//排除x全1
}
allOddBits
/*
* 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) {
//所有奇数位取1返回1
return !((x&0xAAAAAAAA)^0xAAAAAAAA);
}
检查语法不通过
要求只能使用0x0 - 0xff的常量
./dlc权限不够 赋予权限
chmod 777 dlc
/*
* 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) {
//所有奇数位取1返回1(从0开始)
//x先与0xAAAAAAAA按位与,再与0xAAAAAAAA异或,最后取非
//通过0xAA左移
int y = 0xAA;
y = y + (y<<8);
y = y + (y<<16);
return !((x&y)^y);
}
negate
/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x)
{
return ~x + 1;
}
isAsciiDigit
/*
* 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)
{
//判断输入值是否是0-9的ASCII值
//0x30 <= x <= 0x39
//在0x03与0x39之间的数与0x30和0x39+1分别作差符号位必定相反,相同输出0
//右移保持符号位不变!
return !((x + ~0x30 + 1) >> 31) ^ !((x + ~0x3A + 1) >> 31);
}
conditional
/*
* 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 = !!x;
x = ~x + 1;
return (x & y) | (~x & z);
}
isLessOrEqual
/*
* 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)
{
int dValue = y + ~x + 1; //y-x
int dSign = dValue >> 31 & 1; //y-x符号
int sign = 1 << 31;
int xSign = ((x & sign) >> 31) & 1;
int ySign = ((y & sign) >> 31) & 1;
int bitXor = xSign ^ ySign;
return (bitXor & xSign) | ((!bitXor) & (!dSign));
}
logicalNeg
/*
* 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)
{
//逻辑非
//全0返回1 所以要找到0
//0的符号位与0的补码的的符号位 或 的结果为0
//其余的所有二进制数 符号位或的结果为1
//最小值的补码为他本身,所以或的结果为1
//其余数符号位相反,或的结果也为1
return ((x >> 31) | ((~x + 1) >> 31)) + 1;
}
howManyBits
/* 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所需的最小位数
int b16, b8, b4, b2, b1, b0;
int mask = x >> 31;
x = (mask & ~x) | (~mask & x); //如果为正数,保持不变;如果为负数,按位取反
//step1:判断高16为是否有1
b16 = !!(x >> 16) << 4; //如果高16为有1,则b16 = 16,否则为0
x >>= b16; //如果高16为有1,x右移16位舍弃低16位,在新的低16位继续查找;否则保持不变
//step2:判断高8位是否有1
b8 = !!(x >> 8) << 3;
x >>= b8;
//step3:高4位
b4 = !!(x >> 4) << 2;
x >>= b4;
//step4:高2位
b2 = !!(x >> 2) << 1;
x >>= b2;
//step5:高1位
b1 = !!(x >> 1);
x >>= b1;
//step6:低1位
b0 = x;
return b16 + b8 + b4 + b2 + b1 + b0 + 1;
}
floatScale2
c语言中的编码方式:单精度浮点格式(float) —— s、exp和frac字段分别为1位、k = 8位和n = 23位,得到一个32位表示
V
=
(
−
1
)
s
×
M
×
2
E
V=(−1)^s×M×2^E
V=(−1)s×M×2E
尾数( significand)M是一个二进制小数;
阶码( exponent)E的作用是对浮点数加权,这个权重是2的E次幂(可能是负数)。将浮点数的位表示划分为三个字段,分别对这些值进行编码:
一个单独的符号位s直接编码符号s
k位的阶码字段E
e
x
p
=
e
k
−
1
⋯
e
1
e
0
exp = {e_{k - 1}} \cdots{e_1}{e_0}
exp=ek−1⋯e1e0
n位的小数字段M
f
r
a
c
=
f
n
−
1
⋯
f
1
f
0
frac = {f_{n - 1}} \cdots {f_1}{f_0}
frac=fn−1⋯f1f0
//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)
{
//用无符号整数来表示单精度浮点数(float总是带符号的)
//IEEE 754-1985规定 用指数部分全为1,小数部分非0表示NaN
int exp = (uf & 0x7f800000) >> 23; //取出指数部分
int sign = uf & (1 << 31); //取出符号位
if (exp == 255)
return uf;
if (exp == 0)
return uf << 1 | sign;
++exp;
if (exp == 255)
return 0x7f800000 | sign; //exp+1 = uf * 2 返回无穷大
return exp << 23 | (0x807fffff & uf); //否则返回常规uf*2
}
floatFloat2Int
/*
* 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)
{
//阶码的值:E = e - Bias(127)
//尾数的值:M = 1 + frac(隐式编码法,隐含的1)
//1 <= M <= 2
//uf为无符号整数,将其强制转换为单精度浮点数
//1. 规格化的值
int sign = (uf >> 31) & 1;
int exp = (uf >> 23) & 0xff;
int frac = uf & 0x7fffff;
int E = exp - 127;
if (E < 0)
{
return 0;
}
//E>=31时,1.frac*2^E次方加一个符号位,超出int范围
else if (E >= 31)
{
return 0x80000000u;
}
else
{
frac = frac | (1 << 23); //加上隐含的1
if (E < 23) //需要舍弃frac中部分位
{
frac = frac >> (23 - E);
}
else //不需要舍弃部分位
{
frac = frac << (E - 23);
}
}
if (sign)
{
return -frac;
}
else
{
return frac;
}
}
floatPower2
/*
* 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次方
//2.0^x = (1.0*2^1)^x = 1.0*2^x
//exp = E + Bias = E + 127
//x = E
//frac = 1.0 -1 =0
//在denorm中,令frac=000 0000 0000 0000 0000 0001时,M=2.0^22,E=-126
//在denorm中,exp的位全为0,没有隐含的1
int exp = x + 127;
if (x > 127)
{
return (0xff << 23);
}
else if (x < -148)
{
return 0;
}
else if (x >= -126)
{
return (exp << 23);
}
else
{ //令frac中的一位为1
int f = 148 + x;
return (1 << f);
}
语法检查均通过,若最后一个函数超时可以使用命令
./btest -T 20