我有非常基本的代码来从数组中读取原始数据并将其解释为不同类型的数据。代码中的断言失败了,它看起来像是在C中的三元运算符中不正确的重铸。这是针对嵌入式处理器(Analog Devices Tiger Sharc 201)编译的平台。知道这里可能会发生什么吗?我正在联系ADI公司,但我认为总有一个非常聪明的人可以找出可能出错的地方。
#include <assert.h>
typedef union {
unsigned int uint32;
float float32;
} c_t;
int main( int argc, char *argv[] )
{
unsigned int r;
int data_type;
//data is a raw array, could be floats or unsigned int
unsigned int data[] = {470698344};
//cast raw data as mixed union type
c_t mixed = *(c_t*) data;
//interpret all data as unsigned integer
data_type = 1;
//this is where cast to float takes place, resulting in loss of precision
r = data_type ? mixed.uint32 : mixed.float32;
//also fails, with no union, results in same code
//r = data_type ? *((unsigned int *)data) : *((float *) data);
//r = 470698336, loss of precision
//due to incorrect cast inside ternary conditional statement at line 23?
assert(r == 470698344);
return 0;
}
答案 0 :(得分:3)
条件表达式x ? a : b
的类型是表达式a
和b
类型的公共类型。常见类型uint32_t
和float
是...... float
。无论评估两个操作数中的哪一个,其值都将转换为公共类型,这就是条件表达式的值。
您的号码470698344
长度为29位,但您的float
只能达到24位精度。所以在转换中,精度会丢失。当条件表达式的值分配给r
时,这个不太精确的浮点值将被截断为整数,这与470698344
不同。
答案 1 :(得分:1)
在此here
上找到了一个很好的参考不在前面列表中的第二个和第三个操作数的任何组合都是非法的。结果的类型是公共类型,如果第二个和第三个操作数的类型相同且都是l值,则它是一个l值。