2

boost::multiprecision::uint128_t128 ビット値に対してビット演算を実行するために型を使用していました。ただし、128 ビット値をバイナリ ファイルに書き出すのに問題があります。具体的には、値をゼロで埋める必要があります。

例として、uint128_t値が0x12345616進エディタでファイルを見ている場合、次のシーケンスが必要です。

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、128 ビットを 4 つの 32 ビット値として格納しているように見えます。また、使用中の 32 ビット値の数を示す「リム」値があります。32 ビット値が使用されていないときは、0xCCCCCCCC. したがって、ofstream.writeは文字の配列を調べて を書き出し0xCます。

これを正しく書き出すためにブースト ライブラリに欠けているものはありますか?それとも、uint128_t値を別のデータ型に変換する必要がありますか?

4

1 に答える 1

0

私はそれに飛び込みました。隣接する手足を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));
}

16 進ダンプ:

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

残念ながら、これは移植可能ではありません (128 ビット数値用のコンパイラ組み込み関数の可用性に依存する可能性があります)。少なくともタイプセーフです。

于 2015-05-07T01:35:25.933 に答える