6 c bit-manipulation bit-shift
我遇到了这段C代码:
typedef int gint
// ...
gint a, b;
// ...
a = (b << 16) >> 16;
Run Code Online (Sandbox Code Playgroud)
为了便于记法,我们假设b = 0x11223344在这一点上.据我所知,它做了以下事情:
b << 16 会给 0x33440000>> 16 会给 0x00003344因此,丢弃了16个最高位.
为什么有人会写,(b << 16) >> 16如果b & 0x0000ffff也能工作?后一种形式不是更容易理解吗?在这种情况下有没有理由使用位移?是否有任何边缘情况,两者不一样?
假设 的大小int是32位,那么就不需要使用移位。事实上,带有掩码的按位 & 会更具可读性,更便携且更安全。
应该注意的是,负符号整数的左移会引发未定义的行为,并且将东西左移到有符号整数的符号位中也可能会引发未定义的行为。C11 6.5.7(强调我的):
\n\n\n\n\nE1 << E2 的结果是 E1 左移 E2 位位置;空出的\n位用零填充。如果 E1 具有无符号类型,则结果的值为 E1 \xc3\x97 2E2,比结果类型中可表示的最大值多减模 1。如果 E1 具有带符号类型和非负值,并且 E1 \xc3\x97 2E2 可在结果类型中表示,则这就是结果值;否则,行为是未定义的。
\n
(我能想到的唯一可能的理由是,对带有较差编译器的 16 位 CPU 进行了一些过早的优化。如果将算术分解为 16 位块,代码会更有效。但是在这样的情况下一个系统,int很可能是 16 位,所以代码没有任何意义。)
附带说明一下,使用有符号类型也没有任何意义int。此代码最正确、最安全的类型是uint32_t.