19

GMP整数の桁数を決定する簡単な方法はありますか? ログから判断できることは知っていますが、ライブラリに組み込まれているものが欠けているのではないかと思っていました。マニュアルで見つけた唯一のことは次のとおりです。

_mp_size 四肢の数、または負の整数を表す場合はその負数。ゼロは、ゼロに設定された _mp_size によって表されます。この場合、_mp_d データは使用されません。

しかし、私が探しているものとはかなり違うという印象を受けています。

すなわち

124839 = 6 桁。

4

1 に答える 1

17

size_t mpz_sizeinbase (mpz_t op, int base)文字数を取得して、特定のベースの文字列として数値を出力するために使用できます。

size_t mpz_sizeinbase(mpz_t op、int base)

指定されたベースの桁数で測定されたopのサイズを返します。baseは2から62まで変化します。opの符号は無視され、絶対値のみが使用されます。結果は正確であるか、1が大きすぎます。ベースが2の累乗である場合、結果は常に正確です。opがゼロの場合、戻り値は常に1です。

この関数は、opを文字列に変換するときに必要なスペースを決定するために使用できます。割り当ての適切な量は、通常、mpz_sizeinbaseによって返される値より2つ多く、マイナス記号用に1つ、ヌルターミネータ用に1つ追加されます。

したがって、次のようなものがあります。

size_t sz = mpz_sizeinbase (myNum, 10);

良いスタートになるはずです。

正確なサイズが必要な場合は、その値を使用して十分な大きさのバッファーを作成し、その値そのバッファーに出力してから、次のstrlenように、より正確なサイズを取得します。

size_t sz = mpz_sizeinbase (myNum, 10) + 1; // allow for sign
char *buff = malloc (sz + 1);               // allow for `\0`
if (buff != NULL) {
    gmp_sprintf (buff, "%Zd", myNum);
    sz = strlen (buff);
    free (buff);
}

長さを見つけるたびにバッファを割り当てるため、これは最も効率的な方法ではないことに注意してください。割り当てが失敗した場合、デフォルトで最も安全なサイズになります。これは、必要以上に大きくなる可能性があります。

もう1つの可能な方法は、より安全なオプションを使用することです。これは、書き込まれたはずsnprintfのバイト数を返し、バッファオーバーフローを防ぐためです。

char oneChar;
int sz = gmp_snprintf (&oneChar, 1, "%Zd", myNum);

私はそれを具体的にテストしていませんが、これは私が以前に「通常の」Cスタイルの印刷に使用したトリックです。

これらの「正確なサイズ」のソリューションには、前面にオプションの記号が含まれていることに注意してください文字ではなく実際に数字を数えたい場合は、それに合わせて調整する必要があります(たとえば、数が0未満の場合は、サイズから1を引きます)。

于 2011-02-20T16:25:59.020 に答える