Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 有符号类型上的位移位运算符_C_Bit Manipulation_Bitwise Operators_Iso_Bit Shift - Fatal编程技术网

C 有符号类型上的位移位运算符

C 有符号类型上的位移位运算符,c,bit-manipulation,bitwise-operators,iso,bit-shift,C,Bit Manipulation,Bitwise Operators,Iso,Bit Shift,我试图理解有符号和无符号类型上的位运算符的行为。根据ISO/IEC文件,以下是我的理解 左移位运算符 E1 回复:Q1 如果E1为负值,则行为未定义 回复:Q2 无符号算术是“循环的”,也就是说,它是循环的,所以UINT_MAX+1又是0。就好像每一个计算都是模UINT_MAX+1。另一种思考的方式是,不适合左边的多余位被简单地丢弃 回复:第三季度 如果E1为负,则结果为实现定义。也就是说,这取决于您的机器/编译器/选项,但行为必须在某个地方记录(“定义”),通常是在编译器手册中。两种流行的选

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

左移位运算符
  • E1
    • 回复:Q1
      如果E1为负值,则行为未定义

    • 回复:Q2
      无符号算术是“循环的”,也就是说,它是循环的,所以
      UINT_MAX+1
      又是
      0
      。就好像每一个计算都是模UINT_MAX+1。另一种思考的方式是,不适合左边的多余位被简单地丢弃

    • 回复:第三季度
      如果E1为负,则结果为实现定义。也就是说,这取决于您的机器/编译器/选项,但行为必须在某个地方记录(“定义”),通常是在编译器手册中。两种流行的选择是用1(算术移位)或0(逻辑移位)填充左边的输入位


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

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

    本标准第6.5.7节第4段和第5段(n1570草案)中明确提到:

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


    如果您真的想了解按位移位运算符。看看这些简单的规则:

    1) 在左移位中,E1>E2,如果数字为正,则左侧的所有空位将为0,如果数字为负,则为1。请记住,无符号数字永远不会为负。此外,在某些机器上,即使数字为负数,某些实现也可能会将其填充为0,所以千万不要依赖于此

    所有其他场景都可以用这两条简单的规则来解释。 现在,如果您想知道移位后结果的值,只需在纸上写下数字和移位的位表示,并使用这两个规则在空白处输入位。这样,您就能够更好地理解位移动是如何工作的

    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
    
    例如,让我们取int i=7;
    
    iYou忘记了另一条规则:因为某些处理器有一条“按N移位”指令,该指令仅适用于小于字大小的N值,如果要移位的位数超过左侧操作数的大小,则所有下注都将被取消[任何情况都可能发生]。在C89下,对于无符号类型比有符号类型多一个数据位,且无符号类型中的最高有效位与有符号类型的符号位位于同一位置的所有平台,左移负值的行为都得到了精确定义;有效地定义了其他平台上的行为。C99将其更改为未定义的行为,但基本原理没有提到更改,更不用说提供任何原因。是否这样定义的问题取决于是否将C89兼容平台用于普通目标。
    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