“如果该值可以用新类型表示”是什么意思?

问题描述 投票:0回答:2

C11标准

6.3.1.3 有符号和无符号整数

1 当一个整数类型的值转换为另一种整数类型时 除_Bool外,如果该值可以用新类型表示,则 没有变化。

2 否则,如果新类型是无符号的,则该值将转换为 反复加或减 1 比最大值 可以用新类型表示,直到该值在以下范围内 新类型。 60)

3 否则,新类型是有符号的,并且该值不能被 其中所代表的;结果要么是实现定义的,要么是 实现定义的信号被提出。

第一点,

  • 我想知道第一点中的“如果该值可以用新类型表示”是什么意思?两种整数类型可能具有不同的整数范围,但可以具有相同的位表示范围。 (例如,unsigned int 和 int。)

  • 转换前后,位表示形式和整数值都没有改变吗?

谢谢。

c type-conversion integer
2个回答
4
投票

C 标准没有规定整数的一种特定表示形式。虽然您可能遇到的大多数实现都使用二进制补码来表示有符号整数,但这并不能保证。它还允许使用补码,其中对数字求反意味着反转所有位(并且像二进制补码那样加 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
恰好具有相同的表示形式,即十六进制的 FFFFFC18。这种等价适用于补码或符号和数值。

因此,将数字转换为不同类型可能会也可能不会改变表示形式,具体取决于实现。


0
投票

我不明白的是为什么需要这个标准定义,当将负整数转换为更大的无符号数据类型时,它也会导致错误的结果!

所以如果我例如将 -1000 (0xFC18) 作为 I16 (int) 并根据标准将其转换为 U32 (unsigned long) 我将得到 -1000+2^32=4294966296 (0xFFFFFC18) 与预期值 (0x0000FC18) 有很大不同就像我将转换为 I32 一样。

因此,为了将 I16 正确转换为 U32 并获得预期结果,我需要在使用更宽的格式 u32_var=(U32)((U16)u16_var) 之前执行显式的“旧大小无符号转换”?为什么!?

所以理论上标准应该这样写 ” 否则,如果新类型是无符号的,则通过重复加或减比旧类型大小中可以表示为无符号的最大值多一的方式来转换该值,直到该值位于新类型的范围内。 ”

© www.soinside.com 2019 - 2024. All rights reserved.