C语言中的类型转换出了什么问题?

6

我懂得在C语言中类型转换的高级含义。我知道有时候这是隐式完成,而有时候必须显式完成。但是我不清楚这是如何在低级别上实现的:

假设GetSignal返回一个枚举类型

 uint8 outValue;
 f32_t iValue;
 iValue = (f32_t)GetSignal();
 outValue = (uint8)((i32_t)iValue);

我的问题是这里发生了什么。在进行所有的类型转换之后,我不知道位是如何被重新组织的。


有时候并不是真的改变了位,只是告诉编译器“相信我”,这样它就不会抱怨本来会导致类型不匹配的问题。 - Steve Friedl
但是如果要对两种不同类型进行求和,例如尝试将floatint相加时,该怎么办呢?它们都按照各自的标准在其寄存器中排序,如果ALU试图像对2个整数求和一样对它们求和,那么它将返回一个奇怪的结果。因此,我最好的猜测是进行了一些位操作。 - Ricardo Mostalac
3
是的,还有一些位操作的情况,int-to-float(以及反向转换)指示编译器将闻起来像整数的位转换为与浮点类型相同的数值,但通常不需要强制转换,因为编译器可以判断出变量是int类型和float类型,并将它们相加(就像你所建议的那样)。 - Steve Friedl
2
在您的问题中,如果不知道f32_t是什么别名,就很难具体说明。名称(以及函数的名称)表明它是单精度float而不是您所说的enum。这对于强制转换的结果有重大影响。请勿使用我们必须猜测的typedef别名来混淆问题-请使用标准库类型别名的实际数据类型。 - Clifford
你针对@SteveFreidl的_comment_是与所提问的问题不同。SO是一个问答平台,而不是讨论论坛。如果问题紧密相关,请发布新问题或将其添加到现有问题中。 - Clifford
1个回答

4

cast的作用是将一个类型的值转换为另一个类型的值。 对于每种给定类型,该值的表示取决于类型。

假设GetSignal返回一个枚举,其基础值为1。 作为32位整数,它的表示形式如下(假设采用大端字节顺序,即从高到低):

00000000 00000000 00000000 00000001

这个整数值1随后通过显式强制类型转换转换为f32_t。假设该类型被表示为IEEE 754单精度浮点值,则其表示形式(从高到低)如下:

00111111 10000000 00000000 00000000

这个表示法被存储在 iValue 中。

然后将 iValue 强制转换为 i32_t。因此,具有上述 IEEE754 浮点表示的 float 值 1 被转换为带有该表示的 int 值 1:

00000000 00000000 00000000 00000001

这与GetSignal返回的结果相同。然后将该值转换为类型uint8,其表示如下:

00000001

这个表示被存储在outValue中。

关于你对于添加一个float和一个int的评论,通常算术转换规则指定类型为int的值首先会隐式转换为float类型,然后两个float值可以相加,结果的类型为float


re: (uint8)(i32_t)a_float - 如果将浮点数转换为整型时,其值不适合整型,则是未定义的行为;先转换为int32_t,然后再截断为uint8_t是明确定义的。在C标准中,将负double强制转换为unsigned int的行为是否已定义?在ARM和x86上的行为不同 - 这也适用于大于255的浮点数,这些浮点数也不适合uint8_t。因此,如果您有一个浮点数并想要将其整数部分截断为较窄的类型,请先将其转换为足够宽的整数类型。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接