繁体   English   中英

如何输出IEEE-754格式的整数作为浮点数

[英]How to output IEEE-754 format integer as a float

我有一个无符号长整数值,表示使用IEEE-754格式的浮点数。 在C ++中以flo​​at形式打印它的最快方法是什么?

我知道一种方法,但我想知道在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM