C++ 标准不讨论 float 和 double 类型的底层布局,只讨论它们应表示的值的范围。 (对于有符号类型也是如此,是两人的恭维还是别的什么)
我的问题是:用于以可移植方式序列化/反序列化 POD 类型(例如 double 和 float)的技术是什么?目前看来唯一的方法是按字面意思表示值(如“123.456”),ieee754 的 double 布局并不是所有体系结构上的标准。
布莱恩“Beej Jorgensen”霍尔在他的网络编程指南一些要打包的代码float
(resp. double
) to uint32_t
(resp. uint64_t
)能够通过网络在两台可能不同意其表示的机器之间安全地传输它。它有一些限制,主要是它不支持 NaN 和无穷大。
这是他的打包函数:
#define pack754_32(f) (pack754((f), 32, 8))
#define pack754_64(f) (pack754((f), 64, 11))
uint64_t pack754(long double f, unsigned bits, unsigned expbits)
{
long double fnorm;
int shift;
long long sign, exp, significand;
unsigned significandbits = bits - expbits - 1; // -1 for sign bit
if (f == 0.0) return 0; // get this special case out of the way
// check sign and begin normalization
if (f < 0) { sign = 1; fnorm = -f; }
else { sign = 0; fnorm = f; }
// get the normalized form of f and track the exponent
shift = 0;
while(fnorm >= 2.0) { fnorm /= 2.0; shift++; }
while(fnorm < 1.0) { fnorm *= 2.0; shift--; }
fnorm = fnorm - 1.0;
// calculate the binary form (non-float) of the significand data
significand = fnorm * ((1LL<<significandbits) + 0.5f);
// get the biased exponent
exp = shift + ((1<<(expbits-1)) - 1); // shift + bias
// return the final answer
return (sign<<(bits-1)) | (exp<<(bits-expbits-1)) | significand;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)