[英]How to output IEEE-754 format integer as a float
我有一个无符号长整数值,表示使用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”)
你建议的联合方法是大多数人会采用的通常方法。 但是,在C / C ++中,从联合中读取不同的成员而不是最近编写的成员,在技术上是未定义的行为 。 尽管如此,它在几乎所有编译器中得到了很好的支持。
正如Jon Skeet建议的那样 ,转换指针是一个坏主意 - 这违反了C的严格别名规则。积极的优化编译器会为此产生错误的代码,因为它假定类型为unsigned long *
和float *
指针永远不会别名彼此。
在标准合规性方面(即,不调用未定义的行为),最正确的方法是强制转换char*
,因为严格的别名规则允许char*
指针别名指向任何其他类型的指针:
unsigned long ul = 0x40A00000;
float f;
char *pul = (char *)&ul; // ok, char* can alias any type
char *pf = (char *)&f; // ok, char* can alias any type
memcpy(pf, pul, sizeof(float));
老实说,我会选择union方法。 从上面的cellperformance.com链接:
这是一个非常常见的习惯用语,得到了所有主要编译器的良好支持。 实际上,以任何顺序读取和写入工会的任何成员都是可以接受的做法。
编辑:我之前认为这只是“讨厌的”,但事实证明它比我想象的要糟糕 - 详见评论。 我不推荐这种方法,但我将它留在这里以记录可能性(以及警告!)
你可以使用指针:
long ul = 1084227584;
float* fp = (float*) &ul;
float f = *fp;
(这可以压缩成一行,但我认为更清楚。)
基本上和你的工会一样......除非你确定所涉及类型的大小,否则同样狡猾。
如果您的平台支持它们,则应该为整数和浮点类型使用特定于大小的类型名称。
它只适用于32位机器或sizeof(long)== sizeof(float)的机器。 在现代机器上你可能想要使用int而不是......如果你正在执行这个技巧,你必须要小心。
我和Jon Skeet的想法一样,但他打败了我。 但是,我会比他做得更简洁。
cout << "float value is: " << *((float *) &ulValue)) << endl;
你得到一个指向unsigned long的指针,然后将其重新解释为指向float的指针,然后取消引用指向float的指针生成float值。
由于您是在C ++中执行此操作,因此使用reinterpret_cast而不是旧的C样式转换更清晰。
cout << "float value is: " << *(reinterpret_cast<float *>(&ulValue)) << endl;
swegi有正确的方向,但错过了一个角色。 正确的方法是
long l = 1084227584L
float f = reinterpret_cast<float&>(l);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.