Writing boost::multiprecision data type to binary file

两盒软妹~` 提交于 2021-01-28 04:02:18

问题


I was using the boost::multiprecision::uint128_t type in order to perform bitwise operations on a 128 bit value. However I am having trouble writing the 128 bit value out to a binary file. Specifically with the need to pad out the value with zeros.

As an example if the uint128_t value was 0x123456 then looking at the file in the hex editor I would want the sequence:

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();

Instead the binary file ends up with a value:

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

I can see the the boost backend for the uint128_t template appears to store the 128 bits as four 32 bit values. And has a "limb" value which indicates how many 32 bit values are in use. When the 32 bit values are not in use they are filled with 0xCCCCCCCC. So the ofstream.write is walking through the array of characters and writing out the 0xC's.

Is there something I am missing in the boost library to help write this out correctly, or will I need to convert the uint128_t value into some another data type?


回答1:


I dived into it, you can write a utility to write the contiguous limbs as POD objects:

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));
}

Hexdump:

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

I'm afraid this isn't portable (it may depend on the availability of compiler intrinsics for 128 bit numbers). At least it's type safe.



来源:https://stackoverflow.com/questions/30090325/writing-boostmultiprecision-data-type-to-binary-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!