1

I am new to c programming language. What I am trying to do is to get store pi in arbitary precision and turn that to string.

int calculatePIConst (int preciznost)
{
    //init var
    mpfr_t x;
    mpfr_init2 (x, preciznost);
    //populate pi
    mpfr_const_pi (x, MPFR_RNDN);
    //turn to string
    char abc[preciznost];
    int i;
    //error RUN FINISHED; Segmentation fault; core dumped; real time: 90ms; user: 0ms; system: 0ms
    //  mpfr_get_str (abc, i, 50, 50, x, MPFR_RNDN);
    //write pi
    mpfr_printf ("PI = %1.1024RNf\n", x);
    mpfr_clear (x);
    return *abc;
}

Here is mpfr lib documentation documentation http://www.mpfr.org/mpfr-current/mpfr.html#Miscellaneous-Functions

4

5 回答 5

4

最简单的方法是让 MPFR 分配字符串:

char* abc = NULL;
abc = mpfr_get_str (NULL, i, 10, 50, x, MPFR_RNDN);

printf ("PI = %s\n", abc);

mpfr_clear(x);
mpfr_free_str(abc);

还要检查MPFR 的 C++ 包装器中的这个成员函数,例如:

inline std::string mpreal::toString(const std::string& format) const
{
    char *s = NULL;
    std::string out;

    if( !format.empty() )
    {
        if(!(mpfr_asprintf(&s, format.c_str(), mpfr_srcptr()) < 0))
        {
            out = std::string(s);

            mpfr_free_str(s);
        }
    }
    return out;
}

问题是使用 mpfr_asprintf,它自动分配和返回字符串(与 mpfr_get_str 相同),但也允许您使用格式规范。

于 2015-03-17T15:46:16.677 回答
2

从您链接到的文档中:

如果str不是空指针,它应该指向一个足够大的存储块以容纳有效数字,即至少为 max( n + 2, 7)。额外的两个字节用于可能的减号和终止空字符,值 7 表示 -@Inf@ 加上终止空字符。

另外,我假设您希望您的结果以 10 为底,而不是 50 为底。

尝试这个:

char abc[preciznost + 2]; /* assuming preciznost >= 5 */
  :
mpfr_get_str (abc, i, 10, 50, x, MPFR_RNDN);
于 2015-03-17T12:00:50.507 回答
0

你传递什么价值preciznost?我看到调用可以处理非常大的位精度,并且存在使用声明破坏堆栈的危险

char abc[preciznost];

我建议您改为在堆上分配内存,free()稍后再记住。

char *abc = malloc(preciznost);

尽管尚不清楚您将使用此数组做什么。如果它是一个 char 数组'0''1'位值,您将需要一个额外的字节作为nul终止符,所以

char *abc = malloc(preciznost+1);
于 2015-03-17T12:06:10.620 回答
0

原型是:

char *mpfr_get_str (char *str, mpfr_exp_t *expptr, int b, size_t n, mpfr_t op, mpfr_rnd_t rnd)

您的代码中有两个错误的地方:

  1. 数组不够大。请参阅squeamish ossifrage 的答案。但如果您选择使用n等于 0,最好让 MPFR 分配字符串(Pavel Holoborodko 在所有情况下也建议)。

  2. 第二个参数必须是指向 的指针mpfr_exp_t。例如: mpfr_exp_t e; mpfr_get_str (abc, &e, 10, 50, x, MPFR_RNDN);

于 2015-03-20T15:12:55.870 回答
0

根据 Pavel 的回答,我创建了这个函数来输出字符串。

string Autozoom::mpfrToString(const mpfr_t& in) {
    int decimalLocation;
    char* outChar = NULL;

    mpfr_exp_t mpfrDecimalLocation;
    outChar = mpfr_get_str(NULL, &mpfrDecimalLocation, 10, 0, in, MPFR_RNDN);

    decimalLocation = mpfrDecimalLocation;

    string out(outChar);

    if (out[0] == '-') {
        out.insert(decimalLocation + 1, ".");
    }
    else {
        out.insert(decimalLocation, ".");
    }

    return out;
}

这实际上将取小数点的数字,将其插入字符串并返回。

于 2018-05-09T01:51:01.843 回答