C++ Builder String クラスを使用して、浮動小数点数を工学表記法で表示するにはどうすればよいですか? (Unicode文字列)
確かに、これには事前に作成された関数が存在する必要がありますか? 見つかりません。私が遭遇した唯一のものは String::FloatToStrF() ですが、エンジニアリング表記法をサポートしていないようです。
C++ Builder String クラスを使用して、浮動小数点数を工学表記法で表示するにはどうすればよいですか? (Unicode文字列)
確かに、これには事前に作成された関数が存在する必要がありますか? 見つかりません。私が遭遇した唯一のものは String::FloatToStrF() ですが、エンジニアリング表記法をサポートしていないようです。
このサイトからそのまま持ち上げた、工学表記法で印刷するコードを次に示します。私はそれを信用しません。
#define MICRO "µ"
#define PREFIX_START (-24)
/* Smallest power of then for which there is a prefix defined.
If the set of prefixes will be extended, change this constant
and update the table "prefix". */
#include <stdio.h>
#include <math.h>
char *eng(double value, int digits, int numeric)
{
static char *prefix[] = {
"y", "z", "a", "f", "p", "n", MICRO, "m", "",
"k", "M", "G", "T", "P", "E", "Z", "Y"
};
#define PREFIX_END (PREFIX_START+\
(int)((sizeof(prefix)/sizeof(char *)-1)*3))
int expof10;
static unsigned char result[100];
unsigned char *res = result;
if (value < 0.)
{
*res++ = '-';
value = -value;
}
if (value == 0.)
{
return "0.0";
}
expof10 = (int) log10(value);
if(expof10 > 0)
expof10 = (expof10/3)*3;
else
expof10 = (-expof10+3)/3*(-3);
value *= pow(10,-expof10);
if (value >= 1000.)
{ value /= 1000.0; expof10 += 3; }
else if(value >= 100.0)
digits -= 2;
else if(value >= 10.0)
digits -= 1;
if(numeric || (expof10 < PREFIX_START) ||
(expof10 > PREFIX_END))
sprintf(res, "%.*fe%d", digits-1, value, expof10);
else
sprintf(res, "%.*f %s", digits-1, value,
prefix[(expof10-PREFIX_START)/3]);
return result;
}
科学表記法が適している場合は、次を使用できますstringstream
。
std::stringstream s;
double x = 0.0005;
s << std::scientific << x;
これにより、「5.000000e-04」のような結果が得られるはずです。
工学表記法が本当に必要な場合は、次のような変換を自分で記述できます (これが速度のために最適化されているわけではないことはわかっています)。
#include <math.h>
SomeSortOfString floatToEngineering(double x)
{
int exp = 0, sign = 1;
if (x < 0.0) {
x = -x;
sign = -sign;
}
while (x >= 1000.0) {
x /= 1000.0;
exp += 3;
}
while (x < 1.0) {
x *= 1000.0;
exp -= 3;
}
if (sign < 0)
x = -x;
return floatToSomeSortOfString(x) + "e" + intToSomeSortOfString(exp);
}
対数を使用する場合は、これを単純化して、ループした除算/乗算を取り除くことができます。