【问题标题】:Writing boost::multiprecision data type to binary file将 boost::multiprecision 数据类型写入二进制文件
【发布时间】:2015-05-07 09:35:25
【问题描述】:

我使用 boost::multiprecision::uint128_t 类型来对 128 位值执行按位运算。但是,我无法将 128 位值写入二进制文件。特别是需要用零填充值。

例如,如果 uint128_t 的值是 0x123456,那么在十六进制编辑器中查看文件我想要序列:

56 34 12 00 00 00 00 00 00 00 00 00 00 00 00 00

#include <boost/multiprecision/cpp_int.hpp>
#include <fstream>

boost::multiprecision::uint128_t temp = 0x123456;
std::ofstream ofile("test.bin", std::ios::binary);
ofile.write((char*)&temp, 16);
ofile.close();

二进制文件以一个值结束:

56 34 12 00 CC CC CC CC CC CC CC CC CC CC CC

我可以看到 uint128_t 模板的 boost 后端似乎将 128 位存储为四个 32 位值。并且有一个“肢体”值,它指示有多少个 32 位值正在使用中。当 32 位值未使用时,它们将填充为 0xCCCCCCCC。所以ofstream.write 正在遍历字符数组并写出0xC

我在 boost 库中是否缺少一些东西来帮助正确地写出来,还是我需要将 uint128_t 值转换为其他数据类型?

【问题讨论】:

  • (char*) reinterpret_cast 是 evil 并且(显然)不起作用。请参阅有关如何使用 boost 序列化进行序列化的相关答案:stackoverflow.com/a/28705686/85371

标签: c++ boost ofstream multiprecision


【解决方案1】:

我深入研究了它,您可以编写一个实用程序将连续的肢体写入 POD 对象:

Live On Coliru

#include <boost/multiprecision/cpp_int.hpp>
#include <fstream>

template <typename BigInt, typename Backend = typename BigInt::backend_type>
void write_binary(std::ostream& os, BigInt const& number) {
    static_assert(boost::is_pod<typename Backend::local_limb_type>::value, "not allowed");

    os.write(
            reinterpret_cast<char const*>(number.backend().limbs()), 
            number.backend().size()*sizeof(typename Backend::local_limb_type)
        );
}

int main()
{
    using uint128_t = boost::multiprecision::uint128_t;

    std::ofstream ofs("binary.dat", std::ios::binary);
    write_binary(ofs, uint128_t(42));
}

十六进制转储:

0000000: 2a00 0000 0000 0000 0000 0000 0000 0000  *...............

恐怕这不是可移植的(它可能取决于 128 位数字的编译器内在函数的可用性)。至少它是类型安全的。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-15
  • 2013-12-04
  • 2017-05-08
相关资源
最近更新 更多