我有一个无符号长整数值,表示使用IEEE-754格式的浮点数。在C ++中以float形式打印它的最快方法是什么?
我知道一种方法,但我想知道C ++中是否有一个方便的实用程序会更好。
我知道的方式示例如下:
union
{
unsigned long ul;
float f;
} u;
u.ul = 1084227584; // in HEX, this is 0x40A00000
cout << "float value is: " << u.f << endl;
(打印出“浮动值为:5”)
答案 0 :(得分:7)
你建议的工会方法是大多数人会采取的通常方法。但是,在C / C ++中从技术上来说,它是未定义的行为,用于从联合中读取与最近编写的成员不同的成员。尽管如此,它在几乎所有编译器中都得到了很好的支持。
将指针强加为Jon Skeet suggested是一个坏主意 - 这违反了C的strict aliasing规则。积极的优化编译器会为此产生错误的代码,因为它假定类型的指针{ {1}}和unsigned long *
永远不会互为别名。
就标准合规性(即不调用未定义的行为)而言,最正确的方法是强制转换float *
,因为严格的别名规则允许char*
指向别名的指针任何其他类型的指针:
char*
虽然老实说,我会选择union方法。从上面的cellperformance.com链接:
这是一个非常常见的习惯用语,得到了所有主要编译器的良好支持。实际上,以任何顺序读取和写入工会的任何成员都是可以接受的做法。
答案 1 :(得分:3)
您可以使用指针:
long ul = 1084227584;
float* fp = (float*) &ul;
float f = *fp;
(这可以压缩成一行,但我认为更明确的不是。)
与您的工会基本相同......除非您确定所涉及类型的大小,否则同样狡猾。
如果您的平台支持它们,您应该为整数和浮点类型使用特定于大小的类型名称。
答案 2 :(得分:3)
它只适用于32位机器或sizeof(long)== sizeof(float)的机器。在现代机器上你可能想要使用int ...而且如果你正在执行这个技巧,你必须要小心。
答案 3 :(得分:3)
我和Jon Skeet的想法一样,但他打败了我。但是,我会比他更简洁一点。
cout << "float value is: " << *((float *) &ulValue)) << endl;
你得到一个指向unsigned long的指针,然后将其重新解释为指向float的指针,然后取消引用指向float的指针产生浮点值。
由于您是在C ++中执行此操作,因此使用reinterpret_cast而不是旧的C样式转换更清晰。
cout << "float value is: " << *(reinterpret_cast<float *>(&ulValue)) << endl;
答案 4 :(得分:1)
swegi有正确的方向,但错过了一个角色。正确的方法是
long l = 1084227584L
float f = reinterpret_cast<float&>(l);