4

假设我有两个数字,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

我怎样才能做到这一点?

4

2 回答 2

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));
    }
}
于 2012-04-13T20:48:23.297 回答
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      
于 2014-01-16T23:01:25.117 回答