避免在libgmp中中止 [英] avoiding abort in libgmp

查看:128
本文介绍了避免在libgmp中中止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些使用libgmp的代码。在某一点,用户可以请求非常大数的阶乘。不幸的是,这会导致libgmp产生中止信号。

I have some code that uses libgmp. At some point the user may request a factorial of a very large number. Unfortunately, this results in libgmp raising an abort signal.

例如下面的代码:

#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的应用程序,它是中止处理这种问题的最不可取的方法。

Apparently, the number produced is REALLY big. Is there anyway to handle the error more gracefully than an abort. This is a GUI based application and it aborting is pretty much the least desirable way to handle this sort of issue.

推荐答案

在应用程序中优雅地处理这些错误的方式可能是分叉执行GMP计算的助手进程。如果辅助进程被 SIGABRT 杀死,您的父进程可以检测到并向用户报告错误。

The best way to handle these errors gracefully in your application is probably to fork off a helper process to perform the GMP calculations. If the helper process is killed by SIGABRT, your parent process can detect that and report an error to the user.

(下面是我的原始答案,根据GMP文档,它有未定义的结果 - 这是为了完整性)。

如果你为 SIGABRT 安装一个使用 longjmp()的信号处理程序, / code>:

You can catch the error if you install a signal handler for SIGABRT that uses longjmp():

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;
}

这篇关于避免在libgmp中中止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆