C++ 位流到浮点类型强制

C++ 位流到浮点类型强制,c++,c,casting,bit-manipulation,coercion,C++,C,Casting,Bit Manipulation,Coercion,我无法使以下代码正常工作。使用在线IEEE-754转换器,我(手动)写出testData.txt文件,该文件用表示浮点数75.5的位字符串读取;实际的cout.write确实表明位字符串也是我所期望的。但是,当我尝试使用联合将char*强制转换为浮点时(正如我所看到的,这是完成此转换的典型方式),得到的浮点不是我期望的数字 #include<climits> #include<iostream> #include<fstream> #include<bi

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

#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;
}

有什么基本的事情我没有做,这将使这项工作正常吗?

您的工会需要包括一个字符数组,而不是一个指针

union { float f; char c[sizeof(float)]; } float2char;

你也将不得不担心endianness;c[0]是浮点的指数末端,还是尾数的尾部。(答案因硬件而异-Intel vs PPC或SPARC或…

您的工会需要包含字符数组而不是指针

union { float f; char c[sizeof(float)]; } float2char;

你也将不得不担心endianness;c[0]是浮点的指数末端,还是尾数的尾部。(答案因硬件而异-Intel vs PPC或SPARC或…

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

#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;
}
#包括
#包括
#包括
#包括
int main(int,char**)
{
std::ifstream输入文件(“testData.txt”,
std::ios_base::in | std::ios_base::binary);

如果(!inputFile)std::cout您正在使用
位集
的构造函数将ASCII转换为位。这会导致解码位位于
位集
对象中,而不是
联合
。要从位集中获取原始位,请使用
to_ulong
方法:

#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;
}
#包括
#包括
#包括
#包括
int main(int,char**)
{
std::ifstream输入文件(“testData.txt”,
std::ios_base::in | std::ios_base::binary);

如果(!inputFile)std::cout如上所述更改了联合,则使用memcpy调用将缓冲区放入联合的浮点变量,但答案仍然不正确。我使用的是Intel。我发现您没有将sizeof(float)相乘通过字符位…我的问题是否可能与我的文件以ascii手写有关?我认为这是由ifstream ios_base::binary标志解决的。我只需要与浮点中的字节数一样多的字符-因此sizeof(float)是正确的。如果乘以CHAR_位,在大多数机器上会分配一个32字节的值,但大多数浮点类型只有4字节长。我理解你的意思(这是有道理的),但如果是这样的话,我认为我“读取”数据的方式有问题。如果我只读取sizeof(float)字符我只得到一个单词值,即0100而不是01000010100101110000000000000000@bpw1612:您有不同程度的混淆…您的数据由一个由“1”和“0”字符组成的字符串组成,表示每个输入字符串字节的1位信息。您必须将该32字节字符串压缩为32个连续位。然后您可以思考关于将数据提取为浮点数。但是,虽然您的数据量是所需数据量的8倍,但您将遇到问题,而且世界上没有任何工会会有多大帮助。正如我前面所说,我认为@Potatoswatter提供了一个很好的解决方案。我的基本观点是(您不希望工会中有字符指针)仍然有效,但是…@bpw1612:嗯,我想我已经提交了一个评论,可能@Potatoswatter的解决方案比我的更直接地针对目标。我现在看不到它,所以可能我根本没有点击“add”。如上所述更改了联合,使用memcpy调用将缓冲区放在联合的浮点变量上,但答案仍然不正确。我正在使用一个英特尔。我看到你没有用字符位乘以sizeof(float)…我的问题可能与我的文件是用ascii手工写出来的有关吗?我想这是由ifstream ios_base::binary标志解决的。我只需要浮点数中的字节数就可以了-因此sizeof(float)是正确的。如果乘以CHAR_位,在大多数机器上会分配一个32字节的值,但大多数浮点类型只有4字节长。我理解你的意思(这是有道理的),但如果是这样的话,我认为我“读取”数据的方式有问题。如果我只读取sizeof(float)字符我只得到一个单词值,即0100而不是01000010100101110000000000000000@bpw1612:您有不同程度的混淆…您的数据由一个由“1”和“0”字符组成的字符串组成,表示每个输入字符串字节的1位信息。您必须将该32字节字符串压缩为32个连续位。然后您可以思考关于将数据提取为浮点数。但是,虽然您的数据量是所需数据量的8倍,但您将遇到问题,而且世界上没有任何工会会有多大帮助。正如我前面所说,我认为@Potatoswatter提供了一个很好的解决方案。我的基本观点是(您不希望工会中有字符指针)仍然有效,但是…@bpw1612:嗯,我想我提交了一条评论,可能@Potatoswatter的解决方案比我的更直接地针对目标。我现在看不到,所以可能我根本没有点击“添加”。我已经读过你的答案,它确实完全解决了我的问题,所以非常感谢。我将此标记为已回答,但我想看看Jonathan Leffler在我之前介绍了一些不同的东西。我也更愿意使用一种解决方案,将字符数组和无符号长整型作为联合体的另一个成员(因为不清楚如何将联合体扩展到除float之外的任何其他类型,至少对我来说是这样,但在char[]的情况下,它是微不足道的)。@bpw:如果使用
char[]
要存储位数组,每个
char
对象存储8位