【发布时间】:2018-10-03 11:58:19
【问题描述】:
我有两个浮点(32 位)和双精度(64 位)的 IEEE754 二进制表示位集。 如何将此位集转换为 REAL 浮点数或双精度数?
【问题讨论】:
标签: c++ floating-point bitset
我有两个浮点(32 位)和双精度(64 位)的 IEEE754 二进制表示位集。 如何将此位集转换为 REAL 浮点数或双精度数?
【问题讨论】:
标签: c++ floating-point bitset
使用bitset::to_ullong() 和memcpy() 位。
【讨论】:
ulong 将简单地存储 bitset 的任何内容,我们已经知道它在 IEEE754 中。
float或double你memcpy进入的结果将不会有预期价值。
这是一个不依赖于使用 IEEE-754 类型的 C++ 实现的解决方案。
让s 成为bitset 的第一位。
让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 中的所有位(包括符号位)设置为与位集中的确切位匹配。没有便携的方法可以做到这一点。通常必须通过使用memcpy 或其他通过字符类型的复制将位复制到float 或double 对象来完成,并且它要求C++ 实现使用float 或double 类型即 IEEE-754。当然,以上要求C++实现支持NAN和INFINITY,并且C++实现中的浮点类型能够表示值。
【讨论】:
首先,一个不只是代表IEEE 754 floating point。这种表示形式有很多内容。假设您有一个bitset 变量:param,并且您想将其转换为float。为保证这是一次有效的转换,您需要确保:
param.size() == sizeof(float) * CHAR_BITparam 的endianness 匹配endian::native
numeric_limits<float>::is_iec559 是真的param 的基数与numeric_limits<float>::radix 匹配
如果所有这些都是真的,那么这些位实际上是内部浮点表示的格式,并且您可以使用这样的简单函数进行转换(前提是 sizeof(unsigned long) == sizeof(float) 和 sizeof(unsigned long long) == sizeof(double)):
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;
}
【讨论】:
is_iec559 不是一个普遍有用的指标。如果类型(包括算术和其他行为)符合 IEC 60559/IEEE 754,is_iec559 应该为真。但是,许多 C++ 实现使用 IEEE-754 格式但不符合其算术要求,因此不设置 is_iec559 .所以is_iec559 不能作为是否使用 IEEE-754 格式的指标。