C语言 “如果值可以由新类型表示”是什么意思?

k4ymrczo  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(98)

C11标准

6.3.1.3有符号和无符号整数

1当整数类型的值被转换为_Bool以外的另一个整数类型时,如果该值可以用新类型表示,则该值不变。
2否则,如果新类型是无符号的,则通过重复地加或减比可以在新类型中表示的最大值多一个来转换该值,直到该值在新类型的范围内。第六十章)
3否则,新类型是有符号的,不能在其中表示值;或者结果是实现定义的,或者产生实现定义的信号。
在第一点中,

  • 我想知道第一点中的“如果值可以由新类型表示”是什么意思?两个整数类型可能具有不同的整数范围,但可以具有相同的位表示范围。(例如,unsigned int和int。
  • 在转换前后,位表示和整数值都没有改变吗?

谢谢.

bfnvny8b

bfnvny8b1#

C标准没有规定整数的特定表示。虽然你可能遇到的大多数实现都使用二进制补码来表示有符号整数,但这并不能保证。它还允许1的补码,其中对数字求反意味着反转所有位(并且 * 不 * 像2的补码那样加1),或者符号和幅度,其中对数字求反意味着仅反转高阶位。
因此,标准的语言谈论的是整数转换时的 * 值 *,而不是 * 表示 *。
例如,假设int的范围为-231到231-1,unsigned int的范围为0到232-1。如果你有一个值为45的int被转换为unsigned int,这个值可以用两种类型表示,所以现在你有一个值为45的unsigned int
现在假设int的值为-1000。该值不能用unsigned int表示,因此必须按照第2条中的规则进行转换,即232与-1000相加得到232 - 1000 == 4294966296。现在在二进制补码表示中,值为4294966296的unsigned int和值为-1000的int恰好具有相同的表示,即十六进制的FFFFFC 18。这种等价性对于一个人的补数或符号和幅度不成立。
因此,将数字转换为不同的类型可能会也可能不会更改表示,具体取决于实现。

q35jwt9p

q35jwt9p2#

我不明白的是,为什么这个标准定义是必要的,它也导致错误的结果时,铸造负整数到一个更大的无符号数据类型!
所以如果我。把-1000(0xFC 18)作为I16(int),并根据标准将其转换为U32(无符号长),我将得到-1000+2^32=4294966296(0xFFFFFC 18),这与预期的值(0x 000 FC 18)有很大不同,就像我将转换为I32一样。
因此,为了正确地将I16转换为U32并获得预期的结果,我需要在转换为更广泛的格式u32_var=(U32)((U16)u16_var)之前显式地执行“旧大小无符号转换”?为什么啊!
所以理论上标准应该写这样的东西“否则,如果新类型是无符号的,则通过重复增加或减去比可以在旧类型大小中表示为无符号的最大值多一个值来转换值,直到值在新类型的范围内。“

相关问题