将GMP / MPIR编号存储在QList中

时间:2011-05-21 20:06:53

标签: qt4 gmp qlist

我正在尝试使用QT4.7和MPIR库(v.2.3.1)在C ++中编写程序。 在一些计算过程中,我需要存储动态数量的mpz_t(整数存储类型),并希望使用QList或QVarLengthArray。我已经成功地对如何做到这一点进行了基本的测试,但它看起来如此丑陋且完全错误,我想要求更好地做到这一点。

我的示例程序:

#include <QtCore/QCoreApplication>
#include <QList>
#include <qtimer.h>
#include <mpirxx.h>
#include <iostream>

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);
    QList<__mpz_struct> test;

    std::cout << "Write ints 0 to 9 in the QList" << std::endl;

    for (int i = 0; i < 10; ++i) {
        mpz_t zahl;
        mpz_init_set_si(zahl, i);
        test.append(zahl[0]);
    }

    std::cout << "Check if everything is still there." << std::endl;

    for (int i = 0; i < 10; ++i) {
        mpz_t zahl;
        zahl[0] = test.at(i);
        std::cout << mpz_get_str(NULL, 10, zahl) << std::endl;  
    }
    std::cout << "What an ugly hack." << std::endl;

    QTimer::singleShot(0, &a, SLOT(quit()));
    return a.exec();
}

(在Windows 7 / MSVC2010 SP1 / QT4.7.3 / MPIR2.3.1下编译) 输出是正确的,但我怀疑它是一种有效甚至安全的方式来存储mpz_t。

请让我知道如何实现这一目标:)

1 个答案:

答案 0 :(得分:0)

如果您要在很多地方使用存储的数据,在函数等之间传递它,那么我肯定会使用QList,因为它们是implicitly shared

这允许许多好的东西,如下所示:

void listOperation(QList<mpz_t> list)
{
    // Initialize and set
    mpz_t an_int;
    mpz_init_set_si(an_int, 0);
    list.append(an_int);
} 

在这段代码中,我们按值传递'list',因此通常会出现深拷贝(复制所有数据)。但是,由于隐式共享,仅发生浅拷贝(引用副本;指向共享数据块的指针)。此外,即使要非常频繁地调用此函数,QList也会在其内部缓冲区的两侧预先分配额外的空间,因此此操作通常为O(1)(取自QList)文档。

QList(和所有QT的容器类)就像std容器一样 - 它们可以容纳任何类型的对象(甚至是基元和指针)。

使用GMP时出于两个原因,这很棘手。

  1. mpz_t类型是指针,但你不能使用新的
  2. mpz_clear用于清理
  3. 更好的方法可能是使用class interface。这样你就可以用典型的c ++方式将你的mpz_t对象分配为mpz_class对象,而不必担心事情。

    mpz_class an_int = 1234;
    mpz_class *another = new mpz_class(1234);
    

    更新示例: (未编译/测试)

    #include <QtCore/QCoreApplication>
    #include <QList>
    #include <QDebug>
    #include <qtimer.h>
    #include <mpirxx.h>
    #include <iostream>
    
    int main(int argc, char *argv[]) 
    {
        QCoreApplication a(argc, argv);
        QList<mpz_class *> list;
    
        qdebug() << "Write ints 0 to 9 in the QList";
    
        for (int i = 0; i < 10; ++i)
        {
            test.append(new mpz_class(0));
        }
    
        qdebug() << "Check if everything is still there.";
        foreach (mpz_class *item, list)
        {
            qdebug() << *item;
        }
        qdebug() << "Not so bad anymore.";
    
        // Clean up list
        qDeleteAll(list.begin(), list.end());
        list.clear();        
    
        QTimer::singleShot(0, &a, SLOT(quit()));
        return a.exec();
    }