%g を使用した sprintf の最小バッファ サイズはどれくらいですか?

StackOverflow https://stackoverflow.com/questions/1664571

  •  12-09-2019
  •  | 
  •  

質問

問題は、最大精度で %g でフォーマットされた double を出力するのに十分な大きさのバッファを静的に割り当てることです。これは十分に単純なタスクのように思えますが、問題があります。私が思いついた最良の方法は(出力される数値がxであると仮定して)次のとおりです。

char buf[1 + DBL_DIG + DBL_DIG + 1 + 1 + 1 + DBL_DIG + 1];
int len = sprintf(buf, "%.*g", DBL_DIG, x);

DBL_DIG マクロは float.h からのもので、明らかに、double 型の最大精度を示すことになっています。必要なものは次のとおりです。

  • 負符号の場合は 1 バイト
  • 有効数字をキャプチャするのに十分なバイト数
  • 1 桁につき最大 1 つの「区切り文字」 (カンマなど)
  • 小数点1バイト
  • 「e」は 1 バイト
  • 指数上の符号用の 1 バイト
  • 指数用のいくつかのバイト
  • sprintf によって書き込まれた末尾の null 用の 1 バイト。

指数の桁数の上限として有効桁数を使用しています。何か間違いを犯したでしょうか?もっと良い解決策はありますか?64、128、または 256 バイトを割り当てて、最善の結果を期待する必要がありますか?

役に立ちましたか?

解決 4

その代わりsprintfを使用して、あなたが使用することができます<のhref = "http://www.freebsd.org/cgi/man.cgi?query=asprintf&apropos=0&sektion=0&manpath=FreeBSD+7.2-RELEASE&format=html" のrel = "nofollowをnoreferrer"> asprintf の。これはあなたの文字列に合わせて適切なサイズのバッファを割り当てます。

他のヒント

あなたはコンパイル時にサイズを事前に計算することができません。 %のGフォーマッタは、アカウントにロケールをとる(1,000のセパレータ等) http://linux.die.net/man/3/sprintf のを参照してください。安全にサイズを計算する方法について説明ます。

あなたが必要とするどのように多くの文字を見つけるためにsnprintf()を使用します:

#include <float.h> /* DBL_DIG */
#include <stdio.h>
#include <stdlib.h>

int main(void) {
  double x = rand() / (double)RAND_MAX;
  char find_len[1];
  int need_len;
  char *buf;

  need_len = snprintf(find_len, 1, "%.*g", DBL_DIG, x);
  buf = malloc(need_len + 1);
  if (buf) {
    int used = sprintf(buf, "%.*g", DBL_DIG, x);
    printf("need: %d; buf:[%s]; used:%d\n", need_len, buf, used);
    free(buf);
  }
  return 0;
}

あなたはsnprintf()用C99コンパイラが必要です。
snprintf()はC99標準で定義されました。 C89実装はsnprintf()が定義されている必要はなく、それは拡張子として持つ場合C99規格で説明したように、それは「仕事」に必要とされない。

2つのことを:%gは表現の数字のすべてが表示されない、%gは素敵-ため、人間が結果を丸め示しています。あなたが別の結果をご希望の場合は、%Fまたは%eを使用して精度を指定することができます。

は、かなりのsnprintf()を使用するよりも)(sprintfのは絶対に使用しないでください。あなたの場合: int len = snprintf(buf, dimensionof(buf), "%.*f", DBL_DIG, x);

  

私は、64に切り上げ128、またはすべき   256と最高の希望?

はい、ちょうどそれを-.-。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top