3

整数の平均計算結果の最初の 100 桁を表示する必要があります。一連の整数は mpz_t 型の配列に格納され、合計されて mpq_t になり、別の mpq_t (カウント) で除算されます

コード:

mpq_t sum;
mpq_init(sum);
//same for variable count, they are filled from mpz_t

//display for check
gmp_printf("%.Qd\n", sum); <- here everything correct
gmp_printf("%.Qd\n", count); <- here also

mpq_div(sum, sum, count);

//to display with floating point
mpf_t avg;
mpf_init(avg);
mpf_set_q(avg, sum);

gmp_printf("%.100Ff\n", avg);    

最後の行の表示、たとえば sum = 2、count = 3 が間違っています。約 10 ~ 15 桁の後に上限があり、0 で埋められます。(2/3) の場合、0.66666666670000...

だから2つのこと:

  1. 下限/上限を設定したくありません。100 桁の後に切り捨てます。
  2. 100 桁すべてを意味のある数字で埋める

したがって、(2/3)の望ましい出力は次のとおりです。

0.666...666 (100 の 6、最後に 6 もある)

4

1 に答える 1

4

mpf_init2(avg, prec) を使用します。ここで、prec は必要なビット単位の最小精度です。舞台裏では、GMP は (通常) 32 ビットまたは 64 ビットのグループで動作するため、計算の実際の精度は少なくとも要求された精度であることに注意してください。

出力の丸めを防止することはより困難になります。MPFR ライブラリの使用をお勧めします。これはより完全な浮動小数点ライブラリであり、GMP の mpf タイプを置き換えるように設計されています。

コメントが長すぎる……。

100 桁を超える計算には、mpf_int(x) を mpf_init2(x, 333) に変更するだけで済みます。333 ビットでは、少なくとも 100 桁の精度が得られるはずですが、わずかに増やしたい場合があります。

gmp_printf() は最後の桁を切り上げる可能性があるため、切り捨てられた出力を取得するのはよりトリッキーになります。「ほぼ常に」機能するアプローチは、mpf_get_str() を使用して 100 桁を超える精度の文字列を作成し、文字列を切り捨てることです。

「ほぼ常に」というのは、...599999999 などの 9 の長いシーケンスが ...600000000 に丸められ、切り捨てられた文字列に 6 が含まれる可能性があるためです。mpf 計算の精度を上げると、この問題が発生する可能性が低くなります。 .

MPFR には、書式設定された出力の丸めを制御できる mpfr_printf() があります。たとえば、mpfr_printf("%.100RZf, avg) は avg を 100 桁の精度で出力し、ゼロに向かって丸めます。

于 2012-10-09T18:38:48.057 に答える