在本例中,if-语句和位运算是如何相同的?

时间:2022-11-11 20:48:06

I was reading this answer and it is mentioned that this code;

我读了这个答案,上面提到了这个代码;

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

can be replaced with this one;

可以用这个替换;

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

I am having hard time grasping this. Can someone explain how bitwise operators achieve what if statement does?

我很难理解这个。有人能解释一下,位操作符是如何实现if语句的吗?

4 个解决方案

#1


27  

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

Clearly adds data[c] to sum if and only if data[c] is greater or equal than 128. It's easy to show that

显然,当且仅当数据[c]大于或等于128时,才将数据[c]相加。这很容易证明

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

Is equivalent (when data only holds positive values, which it does):

为等效(当数据只包含正值时,即为正):

data[c] - 128 is positive if and only if data[c] is greater or equal than 128. Shifted arithmetically right by 31, it becomes either all ones (if it was smaller than 128) or all zeros (if it was greater or equal to 128).

数据[c] - 128当且仅当数据[c]大于或等于128时为正。从算术上说,它在31之前移位,它可以变成所有的1(如果它小于128)或者所有的0(如果它大于或等于128)。

The second line then adds to sum either 0 & data[c] (so zero) in the case that data[c] < 128 or 0xFFFFFFFF & data[c] (so data[c]) in the case that data[c] >= 128.

然后,在数据[c] >= 128或0xffffff & data[c](即数据[c]) = 128的情况下,第二行添加0和数据[c](即0和0)的和。

#2


3  

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

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

(Note that this hack is not strictly equivalent to the original if-statement. But in this case, it's valid for all the input values of data[].)

(请注意,这种攻击并不严格地等同于原始的if语句。但在本例中,它对所有数据的输入值[]都有效。

(data[c] - 128) >> 31; //this is trying to extract only the sign bit of data[c] when data[c] is greater than or equal to 128, if it is less than 128 then (data[c] - 128) will automatically shift into some negative number thus setting the sign bit.

(数据[c] - 128) >> 31;//当数据[c]大于或等于128时,如果小于128,则(data[c] - 128)将自动转换为负数,从而设置符号位。

and sum += ~t & data[c]; will AND the value data[c] with either 1 or 0 depending upon the complemented value of sign bit.Signifies nothing will be added to sum if value((data[c] - 128)) is negative.

和sum += ~t & data[c];根据符号位的互补值,will和值数据[c]分别为1或0。如果值(数据[c] - 128)为负,则不添加任何内容到sum中。

#3


0  

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

is equal to

等于

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

which means that add data[c] to sum if data[c] - 128 is not negative. So we need to extract sign of data[c] - 128. As data is 32bit int array. So for getting sign, we need to arithmetically shift it 32 - 1 = 31 times. So

也就是说,如果数据[c] - 128不是负的,那么就需要将数据[c]相加。所以我们需要提取数据的符号[c] - 128。因为数据是32位整型数组。为了得到符号,我们需要对它进行算术移位32 - 1 = 31次。所以

int t = (data[c] - 128) >> 31; //where t is the sign of data[c] - 128, 0 for positive and 1 for negative
sum += ~t & data[c]; //Add data[c] in sum if t = 0 i.e when the sign of data[c] - 128 is positive

#4


-1  

int t = (data[c] - 128) >> 31; Here data[c] is int data type and int data type size 4 bytes.if (data[c] - 128) is positive and 31th bit is sign bit and it's value will be 0.if (data[c] - 128) is negative then 31th bit will be 1.then right shift 31times give you only the sign bit. Sorry for poor english

int t = (data[c] - 128) >> 31;这里的数据[c]是int数据类型,int数据类型大小为4字节。如果(数据[c] - 128)为正,第31位为符号位,其值为0。如果(数据[c] - 128)是负的,那么31位将是1。然后右移31次只给你一个符号位。对不起,英语很差

#1


27  

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

Clearly adds data[c] to sum if and only if data[c] is greater or equal than 128. It's easy to show that

显然,当且仅当数据[c]大于或等于128时,才将数据[c]相加。这很容易证明

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

Is equivalent (when data only holds positive values, which it does):

为等效(当数据只包含正值时,即为正):

data[c] - 128 is positive if and only if data[c] is greater or equal than 128. Shifted arithmetically right by 31, it becomes either all ones (if it was smaller than 128) or all zeros (if it was greater or equal to 128).

数据[c] - 128当且仅当数据[c]大于或等于128时为正。从算术上说,它在31之前移位,它可以变成所有的1(如果它小于128)或者所有的0(如果它大于或等于128)。

The second line then adds to sum either 0 & data[c] (so zero) in the case that data[c] < 128 or 0xFFFFFFFF & data[c] (so data[c]) in the case that data[c] >= 128.

然后,在数据[c] >= 128或0xffffff & data[c](即数据[c]) = 128的情况下,第二行添加0和数据[c](即0和0)的和。

#2


3  

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

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

(Note that this hack is not strictly equivalent to the original if-statement. But in this case, it's valid for all the input values of data[].)

(请注意,这种攻击并不严格地等同于原始的if语句。但在本例中,它对所有数据的输入值[]都有效。

(data[c] - 128) >> 31; //this is trying to extract only the sign bit of data[c] when data[c] is greater than or equal to 128, if it is less than 128 then (data[c] - 128) will automatically shift into some negative number thus setting the sign bit.

(数据[c] - 128) >> 31;//当数据[c]大于或等于128时,如果小于128,则(data[c] - 128)将自动转换为负数,从而设置符号位。

and sum += ~t & data[c]; will AND the value data[c] with either 1 or 0 depending upon the complemented value of sign bit.Signifies nothing will be added to sum if value((data[c] - 128)) is negative.

和sum += ~t & data[c];根据符号位的互补值,will和值数据[c]分别为1或0。如果值(数据[c] - 128)为负,则不添加任何内容到sum中。

#3


0  

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

is equal to

等于

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

which means that add data[c] to sum if data[c] - 128 is not negative. So we need to extract sign of data[c] - 128. As data is 32bit int array. So for getting sign, we need to arithmetically shift it 32 - 1 = 31 times. So

也就是说,如果数据[c] - 128不是负的,那么就需要将数据[c]相加。所以我们需要提取数据的符号[c] - 128。因为数据是32位整型数组。为了得到符号,我们需要对它进行算术移位32 - 1 = 31次。所以

int t = (data[c] - 128) >> 31; //where t is the sign of data[c] - 128, 0 for positive and 1 for negative
sum += ~t & data[c]; //Add data[c] in sum if t = 0 i.e when the sign of data[c] - 128 is positive

#4


-1  

int t = (data[c] - 128) >> 31; Here data[c] is int data type and int data type size 4 bytes.if (data[c] - 128) is positive and 31th bit is sign bit and it's value will be 0.if (data[c] - 128) is negative then 31th bit will be 1.then right shift 31times give you only the sign bit. Sorry for poor english

int t = (data[c] - 128) >> 31;这里的数据[c]是int数据类型,int数据类型大小为4字节。如果(数据[c] - 128)为正,第31位为符号位,其值为0。如果(数据[c] - 128)是负的,那么31位将是1。然后右移31次只给你一个符号位。对不起,英语很差