union uint64_t_double {
uint64_t u;
double d;
};
uint64_t double_to_uint64_t(double d) {
union uint64_t_double ud;
ud.d = d;
return ud.u;
}
double uint64_t_to_double(int64_t u) {
union uint64_t_double ud;
ud.u = u;
return ud.d;
}
基本上,我可以将这两个函数转换为宏吗?
我需要这个因为TinyC没有优化(内联)函数调用为clang / gcc。
答案 0 :(得分:2)
#define ReinterpretDoubleAsUint64_t(x) ((union { double d; uint64_t u; }) { x } .u)
#define ReinterpretUint64_tAsDouble(x) ((union { uint64_t u; double d; }) { x } .d)
在C中,代码“( type ){ initializer-list }”是复合文字。它创建一个具有指定类型和初始化的对象。所以:
(union { double d; uint64_t u; }) { x }
创建一个用x
初始化的联合。默认情况下,联合的第一个成员已初始化,因此这是一个double
成员d
已设置为x
的联合。给这个联盟,.u
只是引用一个联盟成员的通常方式。所以:
(union { double d; uint64_t u; }) { x } .u
是联盟的成员u
。当读取除最后一个存储的联合成员之外的联合成员时,将以新类型重新解释联合的字节。因此,这会将double
的字节重新解释为uint64_t
。
这是标准C,但它使用实现定义的行为(值得注意的是,编码double
值的方式取决于实现,double
和uint64_t
是否具有相同的尺寸)。