簡體   English   中英

提升 mpfr_float 的序列化

[英]boost serialization of mpfr_float

我想序列化一個包含 boost::multiprecision::mpfr_float 作為成員的自定義類。 它說此處所述Boost.Serialization文檔中一個類型T是在5種性質的至少一個序列化當且僅當是真,並且這里在多倍文檔,該number類有貫通支持這需要底層后端是可序列化。

對於 Boost.Multiprecision 的mpfr_float類型,我知道:

  1. 它不是原始類型。
  2. 它是一個類類型,但它沒有定義serialize函數。
  3. 它不是指向可序列化類型的指針。
  4. 它不是對 Serializable 類型的引用。
  5. 它不是 Serializable 類型的本機 C++ 數組。

所以,看起來如果我想序列化 mpfr_float 類型,我必須為該類型提供serialize函數。

我的問題是:如何通過自己編寫serialize函數將mpfr_float類型擴展為可序列serialize 我想我需要訪問 mpfr 后端,並使用底層數據,但我不確定如何繼續。 非常感謝有 Boost 序列化先前未序列化類經驗的人的提示。


結論解決方案

根據 sehe 的回復,我得出了一個解決方案,該解決方案以 100 和 1000 的精度進行往返:

namespace boost { namespace serialization { // insert this code to the appropriate namespaces


/**
 Save a mpfr_float type to a boost archive.
 */
template <typename Archive>
void save(Archive& ar, ::boost::multiprecision::backends::mpfr_float_backend<0> const& r, unsigned /*version*/)
{
    std::string tmp = r.str(0, std::ios::fixed);// 0 indicates use full precision
    ar & tmp;
}

/**
 Load a mpfr_float type from a boost archive.
 */
template <typename Archive>
void load(Archive& ar, ::boost::multiprecision::backends::mpfr_float_backend<0>& r, unsigned /*version*/)
{
    std::string tmp;
    ar & tmp;
    r = tmp.c_str();
}

} } // re: namespaces

此解決方案解決了上面第 (2) 項中的需求,這表明需要添加serialize函數。 謝謝您的幫助。

直通支持意味着您確實必須為后端類型添加序列化。

您可以使用與我在此答案中展示的方法相同的方法:

我在這里展示了如何(反)序列化mpq_rational

如果您使用的是4.0.0或更高版本,則可以使用mpfr_fpif_exportmpfr_fpif_import進行序列化/反序列化。

using realtype = number<mpfr_float_backend<100, allocate_stack>>;

#define MPFR_BUFFER_SIZE 1000

    namespace boost {
        namespace serialization {
            template<class Archive>
            void save(Archive& ar, const realtype& x, const boost::serialization::version_type&) {
                static char buffer[MPFR_BUFFER_SIZE];
                FILE* fid = fmemopen(buffer, MPFR_BUFFER_SIZE, "wb+");
                mpfr_fpif_export(fid, const_cast<mpfr_ptr>(x.backend().data()));
                fseek(fid, 0L, SEEK_END);
                long length = ftell(fid);
                ar& length;
                ar& boost::serialization::make_array(buffer, length);
                fclose(fid);
            }

            template<class Archive>
            void load(Archive& ar, realtype& x, const boost::serialization::version_type&) {
                static char buffer[MPFR_BUFFER_SIZE];
                long length = 0;

                ar& length;
                ar& boost::serialization::make_array(buffer, length);

                FILE* fid = fmemopen(buffer, length, "r");
                mpfr_fpif_import(x.backend().data(), fid);
                fclose(fid);
            }

            template<class Archive>
            inline void
                serialize(Archive& ar, realtype& t, const unsigned int file_version) {
                split_free(ar, t, file_version);
            }
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM