【问题标题】:boost serialization of mpfr_float增强 mpfr_float 的序列化
【发布时间】:2015-02-24 18:37:56
【问题描述】:

我想序列化一个包含 boost::multiprecision::mpfr_float 作为成员的自定义类。它在 Boost.Serialization 文档中说 here 类型 T 是可序列化的,前提是至少 5 个属性中的一个为真,而在 Multiprecision 文档中 herenumber 类具有传递支持,这需要底层后端可序列化。

对于 Boost.Multiprecision 的 mpfr_float 类型,我知道:

  1. 它不是原始类型。
  2. 它是一个类类型,但它没有定义serialize 函数。
  3. 它不是指向 Serializable 类型的指针。
  4. 它不是对 Serializable 类型的引用。
  5. 它不是 Serializable 类型的本机 C++ 数组。

所以,如果我想序列化 mpfr_float 类型,我必须为该类型提供 serialize 函数。

我的问题是:如何通过自己编写 serialize 函数来扩展 mpfr_float 类型以使其可序列化?我想我需要访问 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 函数。感谢您的帮助。

【问题讨论】:

    标签: c++ serialization boost mpfr multiprecision


    【解决方案1】:

    直通支持意味着您必须为 backend 类型添加序列化,确实如此。

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

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

    【讨论】:

    • 我相信这个引用的解决方案也确实可以解决我的问题。我会玩弄你的解决方案,然后接受。感谢您的快速回复!
    【解决方案2】:

    如果您使用的是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);
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2021-02-06
      • 2023-03-22
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 2017-03-10
      • 1970-01-01
      • 1970-01-01
      • 2012-03-31
      相关资源
      最近更新 更多