我无法让以下代码正常运行。使用在线IEEE-754转换器,我(手动)写出了testData.txt文件,该文件使用应该表示浮点数75.5的位串读取;实际的cout.write确实显示了位字符串也是我所期望的。但是,当我尝试使用union将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;
}
运行此命令的返回结果是:
cout.write of input from file = 01000010100101110000000000000000
fToCharStarUnion.f = -1.61821e+38 bits = 01000010100101110000000000000000
我有什么基本的东西可以使这项工作正常吗?
答案 0 :(得分:4)
你的联盟需要包含一个char数组而不是一个指针。
union { float f; char c[sizeof(float)]; } float2char;
然后你还要担心字节序;是c [0]浮点数的指数端,或尾数的尾部。 (答案取决于您的硬件 - 英特尔与PPC或SPARC或......)
答案 1 :(得分:3)
您正在使用bitset
的构造函数将ASCII转换为位。这会导致您的解码位位于bitset
对象而不是union
。要从bitset中获取原始位,请使用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;
}
这通常假设您的FPU以与CPU的整数部分相同的字节顺序运行,sizeof(long) >= sizeof(float)
...对double
的保证较少,实际上这个技巧难以为32提供便携性。具有64位FPU的位机。
编辑:现在我已经使联盟的成员大小相等,我看到这段代码对字节序很敏感。解码后的float
将位于big-endian机器上数组的最后一个元素中,即little-endian上的第一个元素。 :v(。也许最好的方法是尝试给联盟的整数成员提供与FP成员完全相同的位数,并在获得to_ulong
后执行缩小强制转换。很难保持可移植性标准你好像是用原始代码拍摄的。