简体   繁体   English

签名类型的按位移位运算符

[英]Bitwise shift operators on signed types

I am trying to understand the behavior of bitwise operators on signed and unsigned types. 我试图理解有符号运算符在有符号和无符号类型上的行为。 As per the ISO/IEC document, following are my understandings. 根据ISO / IEC文件,以下是我的理解。

Left shift Operator 左移算子

  • The result of E1 << E2 , is E1 left-shifted E2 bit positions E1 << E2的结果是E1左移E2位位置

  • The vacated bits on the account of left shift will be filled by zeros. 左移帐户中腾出的位将由零填充。

  • E1 as signed non-negative: E1 << E2 will result to E1 multiplied by 2 power of E2, if the value is representable by the result type. E1作为有符号非负数: E1 << E2将导致E1乘以E2的2次幂,如果该值可由结果类型表示。

  • Q1: What about signed negatives? Q1:签署否定书怎么样?

  • Q2: I am not able to understand on what's meant by "reduced modulo" in the following context. Q2:在下面的上下文中,我无法理解“减少模数”的含义。 "If E1 has an unsigned type, the value of the result is E1 × 2E2 , reduced modulo one more than the maximum value representable in the result type" . “如果E1具有无符号类型,则结果的值为E1×2E2,比结果类型中可表示的最大值减少一个模数”

Right Shift Operator 右移算子

  • The result of E1 >> E2 is E1 right-shifted E2 bit positions. E1 >> E2的结果是E1右移E2位的位置。

  • E1 as signed non-negative/unsigned :The value of the result is the integral part of the quotient of E1 / 2E2 E1为有符号非负/无符号 :结果的值是E1 / 2E2的商的整数部分

  • Q3: For signed negative integers I see, some books defining that the vacant positions will be filled with 1 .Please elaborate more on the use of right shift operator on signed negative int. 问题3:对于有符号的负整数,我看到,有些书定义了空位将填充1详细说明使用右移运算符对带符号的负int。

Q1: The behaviour of the left shift operator on negative values of signed integer types is undefined, as is the behaviour for positive values of signed integer types when the result E1 * 2^E2 is not representable in the type. Q1:左移位运算符对有符号整数类型的负值的行为是未定义的,当结果E1 * 2^E2在类型中无法表示时,有符号整数类型的正值的行为也是如此。

That is explicitly mentioned in section 6.5.7, paragraph 4 and 5 of the standard (n1570 draft): 标准(n1570草案)第6.5.7节第4和第5段明确提到了这一点:

4 The result of E1 << E2 is E1 left-shifted E2 bit positions; 4 E1 << E2的结果是E1左移E2位位置; vacated bits are filled with zeros. 腾出的位用零填充。 If E1 has an unsigned type, the value of the result is E1 × 2^E2 , reduced modulo one more than the maximum value representable in the result type. 如果E1具有无符号类型,则结果的值为E1 × 2^E2 ,比结果类型中可表示的最大值减少一个模数。 If E1 has a signed type and nonnegative value, and E1 × 2^E2 is representable in the result type, then that is the resulting value; 如果E1具有有符号类型和非负值, 并且在结果类型中可以表示E1 × 2^E2 ,那么这就是结果值; otherwise, the behavior is undefined. 否则,行为未定义。

Q2: The reduction modulo one more than the maximum value representable in the unsigned integer type means that the bits that are shifted out on the left are simply discarded. Q2:以无符号整数类型中可表示的最大值为模的减少模数意味着简单地丢弃在左侧移出的位。

Mathematically, if the maximal value of the unsigned type is 2^n - 1 (and it is always of that form), the result of shifting E1 left by E2 bits is the value V in the range from 0 to 2^n - 1 such that the difference 数学上,如果无符号的类型的最大值是2^n - 1 (它是那种形式的总是),移位的结果E1向左E2位为值V的范围为0至2^n - 1这样的区别

(E1 * 2^E2 - V)

is divisible by 2^n , that is, it's the remainder you get when dividing E1 * 2^E2 by 2^n . 可以被2^n整除,也就是说,它是将E1 * 2^E2除以2^n时得到的余数。

Q3: The behaviour upon shifting right negative values of signed integer types is implementation-defined. 问题3:在移位有符号整数类型的负值时的行为是实现定义的。 The most common behaviour (at least on two's complement machines) is an arithmetic shift, that is, the result is the quotient rounded down (towards negative infinity). 最常见的行为(至少在两个补码机器上)是算术移位,也就是说,结果是向下舍入(朝向负无穷大)。

5 The result of E1 >> E2 is E1 right-shifted E2 bit positions. 5 E1 >> E2的结果是E1右移E2位的位置。 If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2^E2 . 如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是E1 / 2^E2的商的整数部分。 If E1 has a signed type and a negative value, the resulting value is implementation-defined. 如果E1具有带符号类型和负值,则结果值是实现定义的。

  • Re: Q1 回复:Q1
    If E1 is negative, the behavior is undefined. 如果E1为负数,则行为未定义。

  • Re: Q2 回复:Q2
    Unsigned arithmetic is "cyclic", that is, it wraps around so UINT_MAX + 1 is 0 again. 无符号算术是“循环”的,也就是说,它是环绕的,因此UINT_MAX + 1再次为0 It's as if every calculation was done modulo UINT_MAX+1. 就好像每个计算都是以模UINT_MAX + 1完成的。 Another way to think about it is that excess bits that don't fit in on the left are simply dropped. 考虑它的另一种方法是简单地删除左边不适合的多余位。

  • Re: Q3 回复:Q3
    If E1 is negative, the result is implementation-defined. 如果E1为负数,则结果为实现定义。 That is, it depends on your machine/compiler/options, but the behavior has to be documented ("defined") somewhere, ususally the compiler manual. 也就是说,它取决于您的机器/编译器/选项,但必须在某处记录(“定义”)行为,通常是编译器手册。 Two popular choices are to fill the incoming bits on the left with 1 (arithmetic shift) or with 0 (logical shift). 两种流行的选择是用左(1算术移位)或0(逻辑移位)填充左边的输入位。

If you really want to understand the bitwise shift operators. 如果你真的想了解按位移位运算符。 Look at these simple rules: 看看这些简单的规则:

1) In left shift, E1 << E2, all the vacant bits on right side will be filled by zeroes, does not matter if the number is signed or unsigned, always zeroes will be shifted in. 1)在左移,E1 << E2,右侧的所有空位都将用零填充,如果数字是有符号或无符号无关紧要,则总是将零移入。

2) In left shift, E1 >> E2, all the vacant bits on left side, will be 0 if number is positive, and will be 1 if number is negative.Keep in mind that an unsigned number is never negative. 2)在左移,E1 >> E2,左侧的所有空位,如果数为正,则为0;如果数为负,则为1。请记住,无符号数从不为负数。 Also some implementations might also fill them with 0 on some machines even if number is negative, so never rely on this. 一些实现也可能在某些机器上用0填充,即使数字是负数,所以永远不要依赖于此。

All other scenarios could be explained by these two simple rules. 所有其他场景可以通过这两个简单的规则来解释。 Now if you want to know the value of result after shifting , just write the bit representation of number and shift manually on paper and enter bits at vacant spaces using these two rules. 现在,如果您想知道移位后结果的值,只需写入数字的位表示并在纸上手动移位,并使用这两个规则在空位处输入位。 Then you would be able to understand better how bit shifting works. 然后你就能更好地理解位移的工作原理。

For example lets take int i = 7;
i<<2
now i = 0000 0000 0000 0000 0000 0000 0000 0111
perform two left shits according to rule 1 would be:

0000 0000 0000 0000 0000 0000 0001 1100

which will give it value of 28 ( E1 * 2E2 = 7 *2*2 = 28), which is same as representated by bit pattern. 它将给出28的值(E1 * 2E2 = 7 * 2 * 2 = 28),这与位模式表示的相同。

Now let me explain the "reduced modulo" thing, well if you are shifting a big number, than the bits on left hand side will be lost, "reduced modulo" compensates for it, So if your resultant value if greater than the maximum value that the data type could hold, the bits on left will be lost , and then: result = (E1*2*E2) % ( maximumValue + 1). 现在让我解释“减少模数”的事情,如果你移动一个大数字,比左边的位将丢失,“减少模数”补偿它,所以如果你的结果值如果大于最大值数据类型可以保持,左边的位将丢失,然后:result =(E1 * 2 * E2)%(maximumValue + 1)。

For various other cases, just keep the above rules in mind , and you are good :) 对于其他各种情况,请记住以上规则,你很好:)

Q2:“降值模数X”在数学中表示“值mod X”,可以在C中写为“value%X”。这部分只是解释整数溢出是如何工作的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM