c++ - C++中double/float类型二进制序列化的可移植性

标签 c++ serialization double portability ieee-754

C++ 标准不讨论 float 和 double 类型的底层布局,只讨论它们应该表示的值的范围。 (对于有符号类型也是如此,是二的恭维还是别的什么)

我的问题是:以可移植方式序列化/反序列化 POD 类型(例如 double 和 float)的技术是什么?目前,这样做的唯一方法似乎是让值按字面意思表示(如“123.456”), double 的 ieee754 布局并不是所有架构的标准。

最佳答案

Brian "Beej Jorgensen"Hall 在他的 Guide to Network Programming 中给出了答案一些代码将 float (resp. double) 打包到 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;
}

关于c++ - C++中double/float类型二进制序列化的可移植性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4733147/

相关文章:

c++ - std::char_traits 中使用的静态方法是一种继承吗?

c++ - 将数据从调用者线程传递到另一个 boost::thread 中的方法

c++ - __next_prime 符号未定义

javascript - Fabric.js toJSON() 方法缺少图像

c++ - 使用 OpenCL 的图像卷积中的参数大小无效

java - JAXB - 可序列化

java - 在android中读取和写入序列化对象

c - C双指针重新分配错误

c# - 在 C# 中使用带有整数的 Math.Ceiling

java - double 和 float 据类型的行为