3

根据标准,运算符 << 为带负号的第一个操作数产生未定义行为。

C++11 5.8.2

The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-
filled. If E1 has an unsigned type, the value of the result is E1 × 2 pow E2,
reduced modulo one more than the maximum value representable in the result type.
Otherwise, if E1 has a signed type and non-negative value, and E1 × 2 pow E2 is
representable in the result type, then that is the resulting value; otherwise,
the behavior is undefined

这是可以理解的,因为内存中整数的布局是实现定义的。

C++11 3.9.1.7

this International Standard permits 2’s complement, 1’s complement and
signed magnitude representations for integral types.

另一方面,该标准似乎并没有准确定义按位 & | 和 ^ 应该做。

C++11 5.11 位与运算符

and-expression:
    equality-expression
    and-expression & equality-expression
1 The usual arithmetic conversions are performed; the result is the bitwise 
AND function of the operands. The operator applies only to integral
or unscoped enumeration operands.

C++11 5.12 按位异或运算符

exclusive-or-expression:
    and-expression
    exclusive-or-expression ˆ and-expression
1 The usual arithmetic conversions are performed; the result is the bitwise
exclusive OR function of the operands. The operator applies only to integral
or unscoped enumeration operands.

C++11 5.13 按位包含 OR 运算符

inclusive-or-expression:
    exclusive-or-expression
    inclusive-or-expression | exclusive-or-expression
1 The usual arithmetic conversions are performed; the result is the bitwise
inclusive OR function of its operands. The operator applies only to integral
or unscoped enumeration operands.

这些运算符的定义完全让我难以理解。它在标准中的其他地方吗?是否为有符号整数定义了结果实现?

作为一个例子,让我们看一下这段代码:

signed char a=-1;
signed char b=3;
signed char c=a&b;

使用 2 的补码,a 是 1111 1111,b 是 0000 0011。最后 c 等于 0000 0011 (+3)。

使用 1 的补码,a 是 1111 1110,b 是 0000 0011。c 等于 0000 0010 (+2) 吗?

使用符号大小,a 是 1000 0001,b 是 0000 0011。c 是否等于 0000 0001 (+1) ?

如果您可以使用 1 的补码或符号幅度访问平台,那么这些平台上的结果是什么?

4

4 回答 4

5

位运算独立地对每个位进行操作,无论每个位在解释为数字类型的一部分时可能意味着什么。

所以是的,10000001 & 00000011 == 00000001不管每个位代表一个符号还是一个值的一部分。

于 2013-01-10T14:37:20.527 回答
0

位运算& | ^符只是对两个操作数中的每一个上的每个位执行其命名操作,具体实现取决于底层类型的表示。

但是,转移的情况有所不同。

例如,考虑一个单字节二进制补码-1= 11111111。然后你右移一个。现在是您的数字127(更改符号)或-1(将 1 移到最高位而不是 0)。如果它是符号幅度表示,则同样适用。为了避免所有这些问题,标准只是禁止它。

于 2013-01-10T14:46:43.080 回答
0

负符号整数的左移和右移按标准处理,以便允许实现使用“算术移位”机器指令。算术右移复制0符号位,与在左侧插入 s的逻辑右移不同。如果从左侧边缘移出的位与符号位不同,则算术左移可能会在某些体系结构上产生溢出异常。因此,右移是实现定义的(因为结果始终有效,但可能因实现而异),而左移是未定义的(因为结果可能是中断。)

按位逻辑运算符产生的位模式是完全指定的,但在有符号整数的情况下,结果可能是一个陷阱值(例如在无效-0的 1 补码或符号幅度架构上)。-0在这种情况下,结果是未定义的行为,根据第 5 节介绍的第 4 段:

如果在计算表达式期间,结果未在数学上定义或不在其类型的可表示值范围内,则行为未定义。

于 2013-01-10T16:11:00.760 回答
-1

结果不取决于机器如何表示整数。

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0

上表显示了一位的值。给定一个 32 位整数,对所有 32 位进行位计算。因此,术语按位。

于 2013-01-10T14:36:50.737 回答