Data Lab主要考察位运算和浮点数运算。
bitXor(x, y)
题目说明:使用按位与&和按位取反~实现异或运算^。
异或运算的定义如下:
$$
a \oplus b = (\lnot a \land b) \lor (a \land \lnot b)
$$
根据分配律和德摩根定律,可以推出:
$$
\begin{align}
a \oplus b
&= (\lnot a \land b) \lor (a \land \lnot b) \\
&= \left(\lnot a \lor (a \land \lnot b) \right)
\land
\left( b \lor (a \land \lnot b) \right) \\
&= \left( \lnot a \lor \lnot b \right) \land
\left ( a \lor b \right) \\
&= \lnot \left( \lnot a \land \lnot b \right) \land
\lnot \left ( a \land b \right)
\end{align}
$$
因此:
1 | /* |
tmin
题目说明:求最小的补码。
对于32位的int型,其补码的取值范围为$-2^{31}$~$2^{31}-1$。
1 | /* |
isTmax(x)
题目说明:若x是最大的补码,则返回1;否则,返回0。
最大的补码x为0x7FFFFFFF,其满足x = ~(x + 1)
。除了0x7FFFFFFF以外,-1也满足该表达式。
~(-1)=0
,而~(0x7FFFFFFF)=-1
,因此,可以使用!!(~x)
排除掉-1。
注意到,关系运算符a == b
等价于 !(a ^ b)
。因此:
1 | /* |
allOddBits(x)
题目说明:给定整数x,若其二进制形式的奇数位(从前往后编号)均为1,则返回1;否则,返回0。
分析:只需要判断x是否等于0xAAAAAAAA即可。
1 | /* |
negate(x)
题目说明:使用位运算求相反数。
1 | /* |
isAsciiDigit(x)
题目说明:若0x30<=x<=0x39(48<=x<=57),则返回1。
48~57的二进制形式如下所示:
1 | 48 => 110000 |
不难发现:
- 若前3位=110,则x一定位于30~39之间;
- 若前5位=11100,则x一定位于30~39之间。
1 | /* |
conditional(x, y, z)
题目说明:实现三目运算符。
$$
f(x, y, z) =
\begin{cases}
\sim\ 0\ \&\ y, & x\neq0\\
\sim\ 0\ \&\ z, & x=0
\end{cases}
$$
而:
$$
!x + \sim 0 =
\begin{cases}
\sim 0, & x \neq 0 \\
0, & x = 0
\end{cases}
$$
因此:
1 | /* |
isLessOrEqual(x, y)
题目说明:实现x<=y。
当x和y的符号不相同时,x必须为负数,即x < 0 <= y;
当x和y的符号相同时,$y + (-x) \ge 0$。
$$
\begin{align}
x \le y
&\Leftrightarrow y - x \ge 0 \\
&= y + (-x) \ge 0
\end{align}
$$
问题一:如何判断一个整数是正数还是负数呢?
对于32位的int型,右移31位,若结果为0,则为正数;若结果为-1,则为负数。
问题二:如何判断两个整数的符号位是否相同呢?
$$
(x >> 31) \oplus (y >> 31) =
\begin{cases}
0, & 符号位相同\\
1, & 符号位不相同
\end{cases}
$$
1 | /* |
logicalNeg(x)
题目说明:实现逻辑非!运算。
$$
!x=
\begin{cases}
1, & x = 0\\
0, & 其他
\end{cases}
$$
分析:只需要判断x是否等于0。
0和其相反数0执行按位或运算,结果的符号位为0;除0以外,任何一个数和它的相反数执行按位或运算,结果的符号位为1,即:
$$
(x | -x) >> 31 =
\begin{cases}
0, & x = 0\\
-1, & 其他
\end{cases}
$$
因此:
$$
!x = ((x | -x) >> 31) + 1
$$
1 | /* |
howManyBits(x)
二分法
1 | /* howManyBits - return the minimum number of bits required to represent x in |
浮点数
给定一个浮点数N,其可以表示为:
$$
N = (-1)^s \times M \times 2^E
$$
其中,s表示符号位;M表示尾数;E表示指数。
单精度浮点数float,占32位,其存储格式为:1个符号位 + 8位阶码 + 23位尾数
双精度浮点数double,占64位,其存储格式为:1个符号位 + 11位阶码 + 52位尾数
移码:
$$
X = E + 2^{n - 1} - 1
$$
floatScale2(x)
1 | /* |
floatFloat2Int(x)
1 | /* |
floatPower2(x)
题目说明:使用位运算求$2.0^x$。
$$
\begin{align}
2.0^x
&= 1.0 \times 2^x
\end{align}
$$
1 | /* |