1

私はcプログラミング言語が初めてです。私がやろうとしているのは、ストア pi を任意の精度で取得し、それを文字列に変換することです。

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

これは 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が NULL ポインターでない場合は、仮数に十分な大きさの記憶域のブロック (つまり、少なくとも max( n + 2, 7)) を指す必要があります。余分な 2 バイトは、可能なマイナス記号と終端のヌル文字用であり、値 7 は -@Inf@ と終端のヌル文字を表します。

また、基数 50 ではなく、基数 10 での結果が必要だと思います。

これを試して:

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

プロトタイプは次のとおりです。

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

コードには 2 つの間違った点があります。

  1. 配列が十分に大きくありません。squeamish ossifrage による回答を参照してください。しかし、0 を使用することを選択した場合nは、MPFR に文字列を割り当てさせる方が適切です (すべてのケースで Pavel Holoborodko によって提案されています)。

  2. 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

どのような値を渡しpreciznostますか? 呼び出しは非常に大きなビット精度を処理できることがわかりました。宣言でスタックを壊してしまう危険性があります。

char abc[preciznost];

後で覚えておいて、代わりにヒープにメモリを割り当てることをお勧めしますfree()

char *abc = malloc(preciznost);

この配列を何に使用するかは不明ですが。'0'またはビット値の char 配列の場合は、ターミネータ'1'用に追加のバイトが必要になるため、nul

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