首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bitstream to Float类型强制

Bitstream to Float类型强制
EN

Stack Overflow用户
提问于 2010-02-19 03:22:44
回答 2查看 1.4K关注 0票数 1

我无法让下面的代码正常工作。使用在线的IEEE-754转换器,我(手动)写出了testData.txt文件,该文件是用表示浮点数75.5的位串读取的;实际的cout.write也显示了位串也是我所期望的。但是,当我尝试使用联合将char*转换为浮点数时(正如我所看到的,这是完成此转换的典型方法),得到的浮点数并不是我期望的数字。

代码语言:javascript
复制
#include<climits>
#include<iostream>
#include<fstream>
#include<bitset>

int main( int, char** )
{

    std::ifstream inputFile( "testData.txt", std::ios_base::in | std::ios_base::binary );
    if( !inputFile ) std::cout << "Failed to open input file!" << std::endl;

    char buffer[ CHAR_BIT * sizeof(float) ];
    inputFile.read( buffer, CHAR_BIT * sizeof(float) );

    std::cout << "cout.write of input from file = ";
    std::cout.write( buffer, CHAR_BIT * sizeof(float) );
    std::cout << std::endl;

    union { float f; char* c; } fToCharStarUnion;

    fToCharStarUnion.c = buffer;
    std::bitset< sizeof(float) * CHAR_BIT > bits( std::string( fToCharStarUnion.c ) );
    std::cout << "fToCharStarUnion.f = " << fToCharStarUnion.f << " bits = " << bits << std::endl;

    inputFile.close();
    return 0;
}

运行此命令的返回结果为:

代码语言:javascript
复制
cout.write of input from file = 01000010100101110000000000000000
fToCharStarUnion.f = -1.61821e+38 bits = 01000010100101110000000000000000

是不是有什么基本的东西我没有做,可以让它正常工作?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-02-19 03:44:17

您正在使用bitset的构造函数将ASCII码转换为位。这会导致解码后的比特位于bitset对象中,而不是union中。要从位集获取原始位,请使用to_ulong方法:

代码语言:javascript
复制
#include<climits>
#include<iostream>
#include<fstream>
#include<bitset>

int main( int, char** )
{

    std::ifstream inputFile( "testData.txt",
       std::ios_base::in | std::ios_base::binary );
    if( !inputFile ) std::cout << "Failed to open input file!" << std::endl;

    char buffer[ CHAR_BIT * sizeof(float) ];
    inputFile.read( buffer, CHAR_BIT * sizeof(float) );

    std::cout << "cout.write of input from file = ";
    std::cout.write( buffer, CHAR_BIT * sizeof(float) );
    std::cout << std::endl;

    union {
        float f[ sizeof(unsigned long)/sizeof(float) ];
        unsigned long l;
    } funion;

    funion.l = std::bitset<32>( std::string( buffer ) ).to_ulong();
    std::cout << "funion.f = " << funion.f[0]
       << " bits = " << std::hex <<funion.l << std::endl;

    inputFile.close();
    return 0;
}

这通常假设您的FPU以与CPU的整数部分相同的字节顺序运行,并且sizeof(long) >= sizeof(float)…对double的保证较少,而且确实很难使其可移植到具有64位FPU的32位机器上。

编辑:现在我已经使联盟的成员大小相等了,我看到这段代码对字节顺序很敏感。解码后的float将位于大端机器上数组的最后一个元素,小端机器上的第一个元素。:v( .也许最好的方法是尝试为联合的整数成员提供与FP成员完全相同的位数,并在获得to_ulong后执行缩小转换。要维护您在原始代码中所追求的可移植性标准非常困难。

票数 3
EN

Stack Overflow用户

发布于 2010-02-19 03:27:21

您的联合需要包含一个字符数组,而不是一个指针。

代码语言:javascript
复制
union { float f; char c[sizeof(float)]; } float2char;

您还必须担心字节顺序;c是浮点数的指数端,还是尾数的尾数。(答案因硬件而异-英特尔与PPC或SPARC或...)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2291533

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档