C++ mpz_class 和二进制文件

标签 c++ pointers binaryfiles gmp

我正在使用 mpz_class(使用 MPIR 2.5.1 和 Visual Studio C++ 2010,以及 C++ 版本的 MPIR),对我来说在内存中存储大量数字是不可行的,所以我想用二进制文件来做.

我已经用文本文件完成了这个,但是当我使用 100,000+ 位数字时,二进制文件应该(希望)节省大量空间。

我写了一个简短的例子来帮助你理解我想做什么:

ofstream binFile;
binFile.open ("binary.bin", ios::out | ios::binary);

mpz_class test;
test.set_str("999999999999999",10);

binFile.write((char *)(&test), sizeof(test));

cout << "NUMBER: " << test << "\tSIZE: " << sizeof(test) << endl;
binFile.close();

我正在尝试编写代表 mpz_class 实例的字符数据。然后,为了测试它,我尝试读取文件:

ifstream binFile2;
binFile2.open("binary.bin", ios::in | ios::binary);

mpz_class num1 = 0; 
binFile2.read ((char *)(&num1), sizeof(num1));

cout << "NUMBER: " << num1 << "\tSIZE: " << sizeof(num1) << endl;
binFile2.close();

我在网上看到的很多例子都使用这种方法将类数据存储到二进制文件中,但我的输出是这样的:

NUMBER: 999999999999999 SIZE: 12

NUMBER: 8589934595      SIZE: 12

为什么不能直接存类数据,然后再读取呢? mpz_class 的实例不可能大小为 12,这是指针的大小吗??

我也试过这个,但我认为这基本上是一样的:

char* membuffer = new char[12]; //sizeof(test) returned 12
binFile2.read (membuffer , sizeof(test));
memcpy(&test, &membuffer, sizeof(test))

如有任何关于如何解决此问题的建议,我们将不胜感激。谢谢。

最佳答案

我认为您需要花更多时间阅读 GMP 手册(第 12.1 节):

Conversions back from the classes to standard C++ types aren’t done automatically, instead member functions like get_si are provided (see the following sections for details).

因此,您可能需要做的是调用 mpz_class::get_strmpz_class::set_str。无论如何,C++ 接口(interface)只是 C API 的轻量包装器,因此您最好使用低级的东西,因为它有更好的文档记录。在这种情况下,您必须使用 mpz_get_strmpz_set_str(对于整数)。

请记住,没有 API 函数可以提供 GMP 数据类型的直接二进制序列化,因此您需要使用字符串。我不确定这些野兽的大小是否有某些限制,所以如果您打算使用这么大的数字,您应该彻底测试您的代码。也许最好的选择是在 base 62(允许的最大值)中提取字符串表示,这样它就不会破坏你的内存(在 base 2 中它会为每一位吃掉一个字节)然后将其写入文件。

关于C++ mpz_class 和二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12186740/

相关文章:

c++ - 拆分 STL vector

c++ - 目标文件中带有 "U" undefined symbol 类型的程序如何在没有任何链接器错误的情况下进行编译?

c++ - 从 begin() 而不是 cbegin() 获取 const_iterator

c++ - 0x5DF9CCC8 处未处理的异常

file-io - Fortran90+ 中具有可分配组件的数据类型的二进制读/写

c - 为什么 struct int 值没有被传递到下一个函数?

c++ - 将 CUDA 添加到 ROS 包

c++ - Emacs auto-complete-c-headers 不适用于引号

将 4 个整数的结构转换为 float

c++ - 最佳实践 - 从函数返回指针