質問
浮動小数点数が整数の場合、後続の小数点または数字がないようにフォーマットするように文字列を作成しますが、大きな数値の科学表記法に切り替えないようにするにはどうすればよいですか?
実行する場合:
float myFloat= 15.6f;
float myInt = 5.0f;
float myLarge = 7000000.0f;
sprintf(out, "my float is %g", myFloat);
sprintf(out, "my int is %g", myInt);
sprintf(out, "my large is %g", myLarge);
次のようになります:
my float is 15.6 my int is 5 my large is 7e+07f
15.6、5、および700000を与える単一のフォーマット文字列がすべて必要です。
編集された原因のコメントはフォーマットを行いません:
それは私が考えたことです。ただし、フォーマット文字列は長いフォーマット文字列に埋め込まれているため、ラッパーは非常に不便です:
sprintf(buf, "%d %g", myInt, myFloat);
どのようにそれをラップしますか?
sprintf(buf, "%d %g", myInt, Wrapper(myFloat));??
Wrapperは何を返すべきですか?またはさらに悪いこと:
sprintf(buf, "%d %s", myInt, Wrapper(myFloat));??
解決
%g
は%e
または%g
で取得できるとは思わない>%f 。
だから、あなたを満足させる単一の printf
引数があるとは思わない。 15.6では、%2.1f
を使用できます。 7000000の場合、%7.0f
を使用できます。
最善の方法は、おそらく値のサイズを調べて正しい printf
引数を適用するラッパー関数を作成することです。
他のヒント
"%。* f"でフォーマットできます。これにより、精度を別のパラメーターとして渡すことができます。 sprintf。過去に0、1、2、または3桁の数字を追加の末尾0なしでうまく表示したいときにこれを使用しました。 double / floatを取り、整数の精度を返す小さなヘルパー関数を作成します(1000倍して、モジュロ10、100、1000を実行します)。次に、"%。* f"でsprintfを呼び出し、ヘルパー関数を呼び出し、フロートを渡します。
Mikeのアプローチは合理的ですが、log10関数を使用して桁数を直接計算し、floorまたはceilを使用して、実際に整数値を持っていることを確認できます。次のようなもの:
#include <math.h>
double x;
...
if (floor(x) == x && x != 0.0) { // x is an non-zero integer value
int digits = floor(log10(fabs(x)+0.5)) + 1;
printf("x is %.*f\n", digits, x);
}
関数呼び出しのチェーンをアンパックし、まず絶対値を取得して引数が非負であることを確認し、既知の整数値に0.5を加算して、10のべき乗のlog10を計算する際に発生する可能性のある丸め誤差を処理しますlog10とfloorを組み合わせて、fabs(x)+0.5よりも小さい10のべき乗の指数を取得し、最後に1を追加してxを表すのに必要な桁数を取得します。以下にサンプル値を示します(OpenOfficeからですが、C log10関数は同様の精度で計算する必要があります):
x log10(x+0.5)
1 0.176091259055681000
9 0.977723605288848000
10 1.021189299069940000
99 1.997823080745730000
100 2.002166061756510000
999 2.999782798454140000
1000 3.000217092972230000
10000 4.000021714181250000
100000 5.000002171466980000
1000000 6.000000217147190000
10000000 7.000000021714720000
100000000 8.000000002171470000
1000000000 9.000000000217150000
%gを%.10gに置き換えて、最大10個の有効数字を表示します