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

Viv*_*ran 7 c iso bit-manipulation bit-shift bitwise-operators

我试图理解有符号运算符在有符号和无符号类型上的行为.根据ISO/IEC文件,以下是我的理解.

左移算子

  • 结果是E1 << E2,E1左移E2位位置

  • 左移帐户中腾出的位将由零填充.

  • E1为有符号非负: E1 << E2如果该值可由结果类型表示,则将E1乘以E2的2次幂.

  • Q1:签署否定书怎么样?

  • Q2:在下面的上下文中,我无法理解"减少模数"的含义."如果E1具有无符号类型,则结果的值为E1×2E2,比结果类型中可表示的最大值减少一个模数".

右移算子

  • 结果E1 >> E2是E1右移E2位的位置.

  • E1为有符号非负/无符号:结果的值是E1/2E2的商的整数部分

  • Q3:对于有符号的负整数,我看到,有些书定义了空位将被填充1.请详细说明使用右移运算符对带符号的负int.

Dan*_*her 8

Q1:左移位运算符对有符号整数类型的负值的行为是未定义的,当结果E1 * 2^E2在类型中无法表示时,有符号整数类型的正值的行为也是如此.

标准(n1570草案)第6.5.7节第4和第5段明确提到了这一点:

4结果E1 << E2E1左移位E2位置; 腾出的位用零填充.如果E1具有无符号类型,则结果的值E1 × 2^E2将比结果类型中可表示的最大值模数减1.如果E1具有有符号类型和非负值,并且E1 × 2^E2在结果类型中可表示,那么这就是结果值; 否则,行为未定义.

Q2:以无符号整数类型中可表示的最大值为模的减少模数意味着简单地丢弃在左侧移出的位.

数学上,如果无符号的类型的最大值是2^n - 1(并且其是形式总是),移位的结果E1由左E2比特是值V的范围从0 2^n - 1,使得差

(E1 * 2^E2 - V)
Run Code Online (Sandbox Code Playgroud)

是整除2^n,也就是说,它的划分,当你剩余E1 * 2^E22^n.

问题3:在移位有符号整数类型的负值时的行为是实现定义的.最常见的行为(至少在两个补码机器上)是算术移位,也就是说,结果是向下舍入(朝向负无穷大).

5结果E1 >> E2E1右移位E2位置.如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是商的整数部分E1 / 2^E2.如果E1具有有符号类型和负值,则结果值是实现定义的.


mel*_*ene 5

  • Re:Q1
    如果E1为负,则行为未定义.

  • 回复:Q2
    无符号运算"循环",也就是说,它环绕这样UINT_MAX + 10一次.就好像每个计算都是以模UINT_MAX + 1完成的.考虑它的另一种方法是简单地删除左边不适合的多余位.

  • Re:Q3
    如果E1为负,则结果为实现定义.也就是说,它取决于您的机器/编译器/选项,但必须在某处记录("定义")行为,通常是编译器手册.两种流行的选择是用左(1算术移位)或0(逻辑移位)填充左边的输入位.