假设我有两个数字,0.0001和0.00001。
当我尝试在C#中使用“e”符号格式化它们时,我得到以下内容:
double val = 0.0001;
Console.Out.WriteLine(val.ToString("e")) //prints 1e-4
double val2 = 0.00001;
Console.Out.WriteLine(val2.ToString("e")) //prints 1e-5
但我想格式化0.0001和0.00001以显示相同的指数:
0.0001〜> 100E-6 0.00001-> 10E-6
我怎样才能做到这一点?
答案 0 :(得分:6)
如果你想要这个结果:
1.0 = 1.00
0.1 = 0.10
0.01 = 0.010
0.001 = 1.00e-3
0.0001 = 0.10e-3
0.00001 = 0.010e-3
0.000001 = 1.00e-6
使用此代码:
class Program
{
/// <summary>
/// Format a value using engineering notation.
/// </summary>
/// <example>
/// Format("S4",-12345678.9) = "-12.34e-6"
/// with 4 significant digits
/// </example>
/// <arg name="format">The format specifier</arg>
/// <arg name="value">The value</arg>
/// <returns>A string representing the value formatted according to the format specifier</returns>
public static string Format(string format, double value)
{
if(format.StartsWith("S"))
{
string dg=format.Substring(1);
int significant_digits;
int.TryParse(dg, out significant_digits);
if(significant_digits==0) significant_digits=4;
int sign;
double amt;
int exponent;
SplitEngineeringParts(value, out sign, out amt, out exponent);
return ComposeEngrFormat(significant_digits, sign, amt, exponent);
}
else
{
return value.ToString(format);
}
}
static void SplitEngineeringParts(double value,
out int sign,
out double new_value,
out int exponent)
{
sign=Math.Sign(value);
value=Math.Abs(value);
if(value>0.0)
{
if(value>1.0)
{
exponent=(int)(Math.Floor(Math.Log10(value)/3.0)*3.0);
}
else
{
exponent=(int)(Math.Ceiling(Math.Log10(value)/3.0)*3.0);
}
}
else
{
exponent=0;
}
new_value=value*Math.Pow(10.0, -exponent);
if(new_value>=1e3)
{
new_value/=1e3;
exponent+=3;
}
if(new_value<=1e-3&&new_value>0)
{
new_value*=1e3;
exponent-=3;
}
}
static string ComposeEngrFormat(int significant_digits, int sign, double v, int exponent)
{
int expsign=Math.Sign(exponent);
exponent=Math.Abs(exponent);
int digits=v>0?(int)Math.Log10(v)+1:0;
int decimals=Math.Max(significant_digits-digits, 0);
double round=Math.Pow(10, -decimals);
digits=v>0?(int)Math.Log10(v+0.5*round)+1:0;
decimals=Math.Max(significant_digits-digits, 0);
string t;
string f="0:F";
if(exponent==0)
{
t=string.Format("{"+f+decimals+"}", sign*v);
}
else
{
t=string.Format("{"+f+decimals+"}e{1}", sign*v, expsign*exponent);
}
return t;
}
static void Main(string[] args)
{
Console.WriteLine("\t1.0 = {0}", Format("S3", 1.0));
Console.WriteLine("\t0.1 = {0}", Format("S3", 0.1));
Console.WriteLine("\t0.01 = {0}", Format("S3", 0.01));
Console.WriteLine("\t0.001 = {0}", Format("S3", 0.001));
Console.WriteLine("\t0.0001 = {0}", Format("S3", 0.0001));
Console.WriteLine("\t0.00001 = {0}", Format("S3", 0.00001));
Console.WriteLine("\t0.000001 = {0}", Format("S3", 0.000001));
}
}
答案 1 :(得分:0)
我想添加一种更简单的方法来做与我的其他答案相同的事情
/// <summary>
/// Format a number with scientific exponents and specified sigificant digits.
/// </summary>
/// <param name="x">The value to format</param>
/// <param name="significant_digits">The number of siginicant digits to show</param>
/// <returns>The fomratted string</returns>
public static string Sci(this double x, int significant_digits)
{
//Check for special numbers and non-numbers
if (double.IsInfinity(x)||double.IsNaN(x)||x==0)
{
return x.ToString();
}
// extract sign so we deal with positive numbers only
int sign=Math.Sign(x);
x=Math.Abs(x);
// get scientific exponent, 10^3, 10^6, ...
int sci=(int)Math.Floor(Math.Log(x, 10)/3)*3;
// scale number to exponent found
x=x*Math.Pow(10, -sci);
// find number of digits to the left of the decimal
int dg=(int)Math.Floor(Math.Log(x, 10))+1;
// adjust decimals to display
int decimals=Math.Min(significant_digits-dg, 15);
// format for the decimals
string fmt=new string('0', decimals);
if (sci==0)
{
//no exponent
return string.Format("{0}{1:0."+fmt+"}",
sign<0?"-":string.Empty,
Math.Round(x, decimals));
}
int index=sci/3+6;
// with 10^exp format
return string.Format("{0}{1:0."+fmt+"}e{2}",
sign<0?"-":string.Empty,
Math.Round(x, decimals),
sci);
}
所以测试代码
double x = 10000*Math.PI;
for (int i = 0; i < 12; i++)
{
Debug.Print("{0,-25} {1,-12}", x, x.Sci(3));
x/=10;
}
产生以下输出:
x x.Sci(3)
31415.9265358979 31.4e3
3141.59265358979 3.14e3
314.159265358979 314
31.4159265358979 31.4
3.14159265358979 3.14
0.314159265358979 314e-3
0.0314159265358979 31.4e-3
0.00314159265358979 3.14e-3
0.000314159265358979 314e-6
3.14159265358979E-05 31.4e-6
3.14159265358979E-06 3.14e-6
3.14159265358979E-07 314e-9