13

从标准(4.7)看来,从 int 到 unsigned int 的转换,当它们都使用相同的位数时,纯粹是概念性的:

如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模 2 n,其中 n 是用于表示无符号类型的位数)。[ 注意:在二进制补码表示中,这种转换是概念性的,位模式没有变化(如果没有截断)。——尾注]

所以在这个方向上,转换保留了位掩码。我不确定标准是否保证从 unsigned int 到 int 的转换相同(再次假设使用相同的位数)。这里的标准说:

如果目标类型是有符号的,如果它可以在目标类型(和位域宽度)中表示,则值不变;否则,该值是实现定义的。

这里的“目标类型”到底是什么意思?例如 2^32-1 不能用 32 位整数表示。这是否意味着它不能在目标类型中表示,因此不能假设位模式将保持不变?

4

3 回答 3

4

int在这种情况下是目标类型。正如您所说,2^32-1 在这种情况下无法表示,因此它是特定于实现的。虽然,我只见过它保留位模式。

编辑:我应该补充一点,在嵌入式世界中,当一个存储位置需要多个位对位相同的表示时,我们经常使用联合。

所以在这种情况下

union FOO {
    int32_t signedVal;
    uint32_t unsignedVal;
} var;

var可以访问var.signedVal以将 32 位存储为有符号整数,var.unsignedVal并将 32 位存储为无符号值。在这种情况下,位将被保留。

于 2013-02-02T18:29:30.777 回答
3

你不能假设任何事情

第一个引号没有说明位掩码保持不变。它可能在二进制补码中相同,但在一个补码或其他表示中不同。

其次,实现定义的意思是实现定义的,你不能假设任何东西。

理论上,每次转换后表示可以完全不同。就是这样。


If you look at it in a realistic way things come more concrete. Usually, int's are stored in two's complement and signed->unsigned preserves the pattern as unsigned->signed does (since the value can be implementation-defined, the cheapest way is doing nothing).

于 2013-02-02T18:30:38.130 回答
1

“目标类型”是指您分配/转换到的类型。

整个段落意味着unsigned int转换为 32 位的 32 位signed int将保持原样,因为该值适合signed int. 如果它们不适合,则取决于它的实现(例如截断)。这意味着它实际上取决于位是否保留或是否更改(无法保证)。

或者换句话说:如果unsigned int使用它的最高有效位,则结果不再是可预测的。否则没有任何变化(除了改变“盒子上的名字”)。

于 2013-02-02T18:28:18.320 回答