我有一些使用libgmp的代码。在某些时候,用户可能会要求非常大量的阶乘。不幸的是,这导致libgmp发出中止信号。

例如下面的代码:

#include <cmath>
#include <gmp.h>
#include <iostream>

int main() {

    mpz_t result;
    mpz_init(result);

    mpz_fac_ui(result, 20922789888000);

    std::cout << mpz_get_si(result) << std::endl;
}

结果是:
$ ./test
gmp: overflow in mpz type
Aborted

显然,产生的数量确实很大。无论如何,是否有比中止更优雅地处理错误的方法。这是一个基于GUI的应用程序,中止几乎是处理此类问题的最不希望的方法。

最佳答案

在您的应用程序中妥善处理这些错误的最佳方法可能是派生一个帮助程序来执行GMP计算。如果帮助程序进程被SIGABRT杀死,则您的父进程可以检测到该进程并将错误报告给用户。

(以下是我的原始答案,根据GMP文档,该结果具有“不确定的结果”-此处出于完整性目的而保留在此处)。

如果您为使用SIGABRTlongjmp()安装信号处理程序,则会捕获该错误:

jmp_buf abort_jb;

void abort_handler(int x)
{
    longjmp(abort_jb, 1);
}

int dofac(unsigned long n)
{
    signal(SIGABRT, abort_handler);
    if (setjmp(abort_jb))
        goto error;

    mpz_t result;
    mpz_init(result);

    mpz_fac_ui(result, 20922789888000);

    std::cout << mpz_get_si(result) << std::endl;

    signal(SIGABRT, SIG_DFL);
    return 0;

    error:
    signal(SIGABRT, SIG_DFL);
    std::cerr << "Caught SIGABRT from GMP.\n";
    return 1;
}

关于c++ - 避免在libgmp中中止,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3558684/

10-11 16:38