2012-04-13 2 views
4

Angenommen, ich habe zwei Zahlen, 0,0001 und 0,00001.Wie formatieren Sie doppelte Werte in das E-Format mit dem angegebenen Exponenten?

Wenn ich versuche, sie zu formatieren „e“ Notation in C#, erhalte ich folgende:

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 

Aber ich würde beide 0,0001 und 0,00001 bis Format wie die gleichen Exponenten wie diese zeigen:

0,0001-> 100e-6 0,00001-> 10e-6

Wie kann ich das erreichen?

+2

Sie haben würden, ein Verfahren zu schreiben, dies zu tun. Die wissenschaftliche Notation gibt an, dass die Zahl vor dem "e" zwischen 1 (einschließlich) und 10 (exklusiv) oder null ist. Anders ausgedrückt, es muss genau eine Stelle vor dem Dezimalpunkt stehen, und wenn diese Zahl Null ist, müssen alle Ziffern rechts vom Dezimalpunkt ebenfalls Null sein. – phoog

+0

Siehe auch diese Frage: http://stackoverflow.com/questions/808104/engineering-notation-in-c –

Antwort

6

Wenn Sie dieses Ergebnis:

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 

Die Verwendung dieser Code:

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)); 
    } 
} 
+0

Vielen Dank, das ist genau das, was ich brauchte. – sbenderli

0

Ich wollte eine einfachere Art und Weise zu tun, die gleiche Sache wie meine andere Antwort hinzufügen

/// <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); 
} 

Also der Testcode

double x = 10000*Math.PI; 
for (int i = 0; i < 12; i++) 
{ 
    Debug.Print("{0,-25} {1,-12}", x, x.Sci(3)); 
    x/=10; 
} 

erzeugt die folgende Ausgabe:

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  
Verwandte Themen