首要问题的答案让值班员搞错了

Top question`s answer gets shift operator wrong?

本文关键字:值班员 错了 答案 问题      更新时间:2023-10-16

在以下问题中:为什么处理已排序的数组比处理未排序的数组快?接受的答案解释了避免给定示例的分支预测的方法。他/她继续用一些按位运算符替换条件语句:

替换:

if (data[c] >= 128)
sum += data[c];

带有:

int t = (data[c] - 128) >> 31;
sum += ~t & data[c];

然而,在他向右移动的行中,他似乎是在对一个潜在的有符号值进行移动,根据这个:

如果移位运算符后的值大于左侧操作数中的位,则结果未定义。如果左边的操作数是无符号的,右边的移位是逻辑移位,所以高位将用零填充。如果左侧操作数为右移可以是也可以不是逻辑移位(即,行为是未定义的(。

是未定义的行为。有人能澄清我是否遗漏了他正在执行的逐位操作的一些内容吗?也可以用外行的术语解释所执行的逐位数操作的意图(假设我们将其解释为符号值移位的某些定义中定义的行为(。

如果data[c] >= 128,那么data[c] - 128将是非负的,所以它的符号位将是0。否则,如果data[c] < 128,则data[c] - 128将为负,因此其符号位将为1

如果我们右移31(假设int是32位,并且右移是算术的,所以定义了是的实现,但很常见(,那么当data[c] >= 128时,我们将具有0x00000000,当data[c] < 128时,我们具有0xffffffff

如果我们随后逐位反转该值,那么当data[c] >= 128时我们将具有0xffffffff,或者当data[c] < 128时具有0x00000000

如果我们将该值与data[c]进行位"与"运算,则当data[c] >= 128时我们将具有data[c],当data[c] < 128时我们将获得0x00000000

0添加到sum没有任何作用,因此我们有效地只添加大于或等于128的值,而不进行分支。