11

与数字的不同二进制表示一样(例如,采用大/小端),这是跨平台的:

// NOTE: FIXED-SIZE unsigned integral type
some_unsigned_type variable = some_number;

// set n-th bit, starting from 1,
// right-to-left (least significant-to most significant)
variable |= ( 1 << ( n - 1 ) );

// clear the same bit:    
variable &= ~( 1 << ( n - 1 ) );

换句话说,编译器是否总是处理固定大小无符号数的不同二进制表示,或者它是特定于平台的?

如果variable是有符号整数类型(例如int),它的值是

  • 积极的
  • 消极的?

标准对此有何评论?

PS 而且,的,我对这两种语言都很感兴趣-C而且C++,请不要告诉我它们是不同的语言,因为我知道这一点:)

如果需要,我可以粘贴真实示例,但帖子会变得太长

4

3 回答 3

6

除非some_unsigned_type是固定宽度类型,否则这是您的第一个特定平台。在一个平台上,您可能会转移一些价值本身永远不会重现的信息,而在另一个平台上可能不会。例子:

16 bit 'int':

      1000 0000  0000 0000
<<1 = 0000 0000  0000 0000
>>1 = 0000 0000  0000 0000

32 bit 'int':

      0000 0000  0000 0000   1000 0000  0000 0000
<<1 = 0000 0000  0000 0001   0000 0000  0000 0000
>>1 = 0000 0000  0000 0000   1000 0000  0000 0000

5.8 Shift Operators在 C++ 标准中也这样说:

如果右操作数为负数,或者大于或等于提升的左操作数的位长度,则行为未定义。

因此,如果您将一个整数移动的位数多于实际位数,则会输入未定义的行为。例如,如果您将一个值左移short17 位,它可能会在某些机器上为您提供 UB,但不是全部。

C11 在 中说6.5.7 Bitwise shift operators,除其他外,这是:

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

所以有符号数移位是不可移植的。

所以,一般整数的一般答案

整数的按位操作是不可移植的。

于 2012-10-04T15:16:19.127 回答
5

免责声明:我隐含地假设您正在谈论具有固定宽度的整数类型。否则位移是非常危险的......

标准:n3337 C++11

对于无符号类型或有符号类型 (*) 中的正值,移位的定义是数学的,因此不受底层硬件表示的影响。

5.8 移位运算符 [expr.shift]

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

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

出于同样的原因,我认为按位and,ornegate是可以的:它们是在数学上定义的。

5.3.1 一元运算符 [expr.unary.op]

10的操作数˜应为整数或非范围枚举类型;结果是其操作数的反码。

5.11 按位与运算符 [expr.bit.and]

1执行通常的算术转换;结果是操作数的按位与函数。该运算符仅适用于整数或无范围的枚举操作数。

5.13 按位包含 OR 运算符 [expr.or]

1执行通常的算术转换;结果是其操作数的按位包含 OR 函数。该运算符仅适用于整数或无范围的枚举操作数。

但是我承认我对后两者不太确定,我找不到按位 XX 函数的任何定义,所以即使我相信它们指的是数学对应物,我也不能保证。

(*) 感谢 phresnel 指出这一点。

于 2012-10-04T15:35:52.523 回答
1

如果您移动负(或有符号)数字(通过大多数实现是相同的 U2 事物),它是特定于实现的。如果您将无符号数字移动的值不超过变量中的位数,它对于大多数用途都是可移植的。

于 2012-10-04T16:34:47.987 回答