2012-08-29 91 views
0

我正在使用mpz_class(使用MPIR 2.5.1與Visual Studio C++ 2010和C++版本的MPIR),對我而言,將大量數字存儲在內存中是不可行的,所以我想用二進制文件做。C++ mpz_class和二進制文件

我已經完成了這個文本文件,但是當我使用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)) 

關於如何解決此問題的任何建議,將不勝感激。謝謝。

+2

您是否聽說過[pimpl idiom](http://www.gamedev.net/page/resources/_/technical/general-programming/the-c-pimpl-r1794)?這可能是爲什麼該對象只有12個字節。除非你自己編寫了這個類,並且知道它如何使用內存,否則通常不能通過複製對象的內存內容來將任意對象序列化到磁盤上,因爲它可能會,例如,參考堆分配的數據,其他對象等 – Cameron

+0

不,我還沒有聽說過它,我也不知道這個類是如何使用內存的 - 我希望有一種方法可以找出它實際使用了多少內存,用分隔符寫入bin文件,但我不知道如何(如果可能)做到這一點。我認爲這個類幾乎可以動態地分配數據,所以沒有辦法將它序列化? –

回答

1

我認爲你需要花更多的時間與GMP手冊(9.1節):

轉換從類標準C++類型回都沒有做 自動,而不是提供像get_si成員函數(有關詳細信息,請參閱 以下部分)。

所以,你可能需要做的是打電話mpz_class::get_strmpz_class::set_str。無論如何,C++接口只是C API的一個輕量級包裝器,所以你最好使用底層的東西,因爲它有更好的文檔記錄。在這種情況下,您將不得不使用mpz_get_strmpz_set_str(用於整數)。

請記住,沒有API函數可以提供GMP數據類型的直接二進制序列化,因此您需要使用字符串。我不確定這些野獸的大小是否有一定的限制,所以如果你打算使用這麼大的數字,你應該徹底地測試你的代碼。也許最好的選擇是提取一個以62爲底的字符串表示(允許的最大值),這樣它就不會炸燬你的內存(在基本2中它會佔用每個字節一個字節),然後將它寫入文件。