我有两个IEEE754二进制表示位集,分别是float(32bit)和double(64bit)。 如何将这些位集转换为实数浮点数或双数?
答案 0 :(得分:4)
使用bitset::to_ullong()
和memcpy()
位。
答案 1 :(得分:1)
这是不依赖于使用IEEE-754类型的C ++实现的解决方案。
让s
是位集的第一位。
分别将e
设为32位或64位的下8位或11位。
让f
分别为剩余的23或52位。
让Ebias
分别为127或1023。
让Emax
分别为255或2047。
让Fscale
分别为0x1p-23或0x1p-52。
然后,此代码返回解释为IEEE-754基本二进制浮点对象的位集的值:
// Interpret the sign.
double S = s ? -1 : +1;
// Classify the exponent.
if (e == 0)
// The value is zero or subnormal.
return S * std::ldexp(f*Fscale, 1-Ebias);
else if (e < eMax)
// The value is normal.
return S * std::ldexp(1 + f*Fscale, e-Ebias);
else
// The value is NaN or infinite.
if (f == 0)
// The value is infinite.
return S * INFINITY;
else
// The value is a NaN.
return NAN;
这不会将NAN中的所有位(包括符号位)设置为与位集中的确切位匹配。没有便携式的方法可以做到这一点。通常,必须使用float
将这些位复制到double
或memcpy
对象中,或者通过字符类型进行其他复制,并且要求C ++实现使用{{ 1}}或float
类型,即IEEE-754。并且,当然,以上要求C ++实现支持double
和NAN
,并且C ++实现中的浮点类型必须能够表示该值。
答案 2 :(得分:0)
首先,一个不仅仅代表IEEE 754 floating point。这种表示有很多。假设给您一个bitset
变量:param
,并且您想将其转换为float
。为了确保这是一次有效的转化,您需要确保:
param.size() == sizeof(float) * CHAR_BIT
param
的编码来源endianness与endian::native
匹配numeric_limits<float>::is_iec559
是真的param
所编码的基数与numeric_limits<float>::radix
匹配如果所有这些都是正确的,那么这些位实际上就是内部浮点表示形式的格式,您可以使用以下简单函数进行转换(前提是sizeof(unsigned long) == sizeof(float)
和sizeof(unsigned long long) == sizeof(double)
):< / p>
double foo(const bitset<sizeof(double) * CHAR_BIT>& param) {
const auto val = param.to_ullong();
double result;
memcpy(&result, &val, sizeof(double));
return result;
}
float foo(const bitset<sizeof(float) * CHAR_BIT>& param) {
const auto val = param.to_ulong();
float result;
memcpy(&result, &val, sizeof(float));
return result;
}