Engineering notation in C#?
Asked Answered
C

11

14

Is there any code out there (or a built-in function) which allows outputting a floating point number in engineering notation?

For example, 1.5e-4 would be displayed as 150µ and 5e-3 would be displayed as 5m.

Caraviello answered 30/4, 2009 at 17:24 Comment(3)
There's nothing built in. However this forum thread has some code examples: techtalkz.com/c-c-sharp/…Bine
"Engineering Notation" can also be formatted as scientific notation (i.e. using numerical power-of-three exponents rather than letters). It's a real shame these two options aren't available in the standard printf-type libraries: virtually every scientific calculator can do the numeric version of Engineering notation as standard, but I know of no programming language that supports it natively. I have resorted to writing my own converters in Java and Python, but it would be nice if I didn't have to redo this every time I needed to use a different language!Haemolysin
What should be printed with a value just less than one thousand like 999.9999999? do you expect "1k" or "1000"?Desdee
P
13

This may need refactoring:

private static string ToEngineeringNotation(this double d)
{
    double exponent = Math.Log10(Math.Abs(d));
    if (Math.Abs(d) >= 1)
    {
        switch ((int)Math.Floor(exponent))
        {
            case 0: case 1: case 2:
                return d.ToString();
            case 3: case 4: case 5:
                return (d / 1e3).ToString() + "k";
            case 6: case 7: case 8:
                return (d / 1e6).ToString() + "M";
            case 9: case 10: case 11:
                return (d / 1e9).ToString() + "G";
            case 12: case 13: case 14:
                return (d / 1e12).ToString() + "T";
            case 15: case 16: case 17:
                return (d / 1e15).ToString() + "P";
            case 18: case 19: case 20:
                return (d / 1e18).ToString() + "E";
            case 21: case 22: case 23:
                return (d / 1e21).ToString() + "Z";
            default:
                return (d / 1e24).ToString() + "Y";
        }
    }
    else if (Math.Abs(d) > 0)
    {
        switch ((int)Math.Floor(exponent))
        {
            case -1: case -2: case -3:
                return (d * 1e3).ToString() + "m";
            case -4: case -5: case -6:
                return (d * 1e6).ToString() + "μ";
            case -7: case -8: case -9:
                return (d * 1e9).ToString() + "n";
            case -10: case -11: case -12:
                return (d * 1e12).ToString() + "p";
            case -13: case -14: case -15:
                return (d * 1e15).ToString() + "f";
            case -16: case -17: case -18:
                return (d * 1e15).ToString() + "a";
            case -19: case -20: case -21:
                return (d * 1e15).ToString() + "z";
            default:
                return (d * 1e15).ToString() + "y";
        }
    }
    else
    {
        return "0";
    }
}
Priestess answered 30/4, 2009 at 18:7 Comment(2)
If you want to be really pedantic, there should also be a space between the number and the unit (Ref: en.wikipedia.org/wiki/…).Haemolysin
@DrAl, a non-breaking space ;o) en.wikipedia.org/wiki/…Johannessen
N
8

Here's a link to some Ruby code that does something similar, though it formats as dddem, where m, the exponent, is always a multiple of 3.

Transliteration to C#. Since I'm not familiar with the format I'm not sure this does exactly what you want. For example, 0.0015 formats as 2e-3. It would be reasonably trivial to substitute the Greek letters for the exponent using a case statement and UTF-8 or other encodings. The exercise is left to the reader.

public static class FormatExtensions
{
    public static string ToEngineering( this double value )
    {
        int exp = (int)(Math.Floor( Math.Log10( value ) / 3.0 ) * 3.0);
        double newValue = value * Math.Pow(10.0,-exp);
        if (newValue >= 1000.0) {
            newValue = newValue / 1000.0;
            exp = exp + 3;
        }
        return string.Format( "{0:##0}e{1}", newValue, exp);        
    }
}

Usage:

Console.WriteLine( ((double)15000).ToEngineering() );
double val = 15000;
Console.WriteLine( val.ToEngineering() );
Neoteny answered 30/4, 2009 at 17:49 Comment(1)
If value <= 0, Math.Log10(value) will return NaN. You need to consider this case. Also I'm not sure there will not be rounding problems.Johannessen
A
6

Rather than subclassing, I'd take advantage of the fact that Double implements IFormattable and write an IFormatProvider that formats the number. Then I'd have code that looks similar to:

double d = 123.45;
Console.WriteLine(d.ToString(null, new MyCustomFormat()));
Armalda answered 30/4, 2009 at 19:12 Comment(0)
M
1

Combining two of the earlier answers and adding a unit (volt, etc.) gives nice tidy answers like 11000 volts as 11kV.

public static string ToEngineering(this double value, string unitName)
{
    int exp = (int)(Math.Floor(Math.Log10(value) / 3.0) * 3.0);
    double newValue = value * Math.Pow(10.0, -exp);
    if (newValue >= 1000.0)
    {
        newValue = newValue / 1000.0;
        exp = exp + 3;
    }
    var symbol = String.Empty;
    switch (exp)
    {
        case 3:
            symbol = "k";
            break;
        case 6:
            symbol = "M";
            break;
        case 9:
            symbol = "G";
            break;
        case 12:
            symbol = "T";
            break;
        case -3:
            symbol = "m";
            break;
        case -6:
            symbol = "μ";
            break;
        case -9:
            symbol = "n";
            break;
        case -12:
            symbol = "p";
            break;
        }

    return string.Format("{0:##0.000} {1}{2}", newValue, symbol, unitName);
}
Monogyny answered 9/11, 2016 at 11:50 Comment(0)
A
1

Here is another version that handles negative and without rounding

public static string ToEngineering(this double value)
{
    var absValue = Math.Abs(value);
    var exp = absValue < 0.001 ? 0 : (int)(Math.Floor(Math.Log10(absValue) / 3.0) * 3.0);
    var newValue = value * Math.Pow(10.0, -exp);
    return $"{newValue}e{exp}";
}
Anstus answered 18/12, 2017 at 15:18 Comment(1)
This is not what the question asked, but upvoted as this is what I was searching for and the search engines pointed me to this. May pay to post a separate question and answer, with the content above specifically for people that only want the just the numbered notation, not the SI prefixes.Harwell
O
1

I came here looking for a function that can take any numeric representation e.g. signed/unsigned int, float, double, decimal, numeric string, and while I found some inspiration Patrick McDonald's answer, I didn't find the full answer I was looking for, so I wrote my own solution that takes a numeric string, which can be obtained easily from any numeric type. I am sharing my solution in this thread for others to use if they wish to have something more generic:

public static string ToEngineeringNotation(string originalString, int? significantFigures = null)
{
  var str = originalString;

  // remove spaces and negative sign

  str.Replace(" ", "");
  string prefix = "";
  if (str[0] == '-')
  {
    str = str.Substring(1);
    prefix = "-";
  }

  // Get the exponent, remove the exponent nomenclature

  int exponent = 0;
  int exponentStrIndex = 0;
  if ((exponentStrIndex = str.IndexOfAny("Ee".ToArray())) >= 0)
  {
    string exponentStr = str.Substring(exponentStrIndex + 1);
    str = str.Substring(0, exponentStrIndex);
    Int32.TryParse(exponentStr, out exponent);
  }

  // remove the decimal point, and adjust the exponent so the decimal point
  // should go just after the first digit, and trim trailing zeros

  int currentDecimalPosition = str.IndexOf('.');
  if (currentDecimalPosition >= 0)
  {
    exponent += currentDecimalPosition-1;
    str = str.Replace(".", "");
  }
  else
  {
    exponent += str.Length - 1;
  }
  str = str.TrimEnd('0');

  // At this point we should only have digits, just return the original string if we don't

  if (!str.All(char.IsDigit))
  {
    return originalString;
  }

  // Trim leading zeros, the decimal point is effectively moved as it's
  // just after the first digit, so adjust the exponent

  int lengthBefore = str.Length;
  str = str.TrimStart('0');
  exponent += str.Length-lengthBefore;

  // Put the decimal point back in, but move the decimal point right
  // according to the shift worked out above.

  if (significantFigures.HasValue && significantFigures.Value < str.Length)
  {
    if (str.Length >= significantFigures.Value && str[significantFigures.Value] >= '5' && Int64.TryParse(str.Substring(0, significantFigures.Value), out var integerValue))
    {
      // Need to round up
      str = (integerValue + 1).ToString();
      if(str.Length> significantFigures.Value)
      {
        ++exponent;
      }
    }
    str = str.Substring(0, significantFigures.Value);
  }

  // work out how much we need to shift the decimal point to get
  // engineering notation

  var decimalShiftRequired = exponent % 3;
  if (decimalShiftRequired < 0)
    decimalShiftRequired += 3;

  if (exponent == 0)
  {
    decimalShiftRequired = 0;
  }
  str = str.PadRight(1 + decimalShiftRequired, '0');
  str = $"{str.Substring(0, 1 + decimalShiftRequired)}.{str.Substring(1 + decimalShiftRequired)}";
  exponent -= decimalShiftRequired;

  // Remove the decimal point if there are no digits after it
  str = str.TrimEnd('.');

  // Create a default suffix consisting of the exponent
  string suffix = exponent != 0 ? $"E{(exponent < 0 ? "" : "+")}{exponent}" : "";

  // Work out which letter to put on the end, if any. If no letter is found,
  // then the Exponent suffix above will be added without modification

  switch (exponent)
  {
    case 3:
      suffix = "k"; break;
    case 6:
      suffix = "M"; break;
    case 9:
      suffix = "G"; break;
    case 12:
      suffix = "T"; break;
    case 15:
      suffix = "P"; break;
    case 18:
      suffix = "E"; break;
    case 21:
      suffix = "Z"; break;
    case 24:
      suffix = "Y"; break;
    case -3:
      suffix = "m"; break;
    case -6:
      suffix = "μ"; break;
    case -9:
      suffix = "n"; break;
    case -12:
      suffix = "p"; break;
    case -15:
      suffix = "f"; break;
    case -18:
      suffix = "a"; break;
    case -21:
      suffix = "z"; break;
    case -24:
      suffix = "y"; break;
  }
  return $"{prefix}{str}{suffix}";
}

Here's the comment block that goes at the top of the above function, I've put it here at the end so people don't have to scroll through it to get to the code:

/// <summary>
/// Converts a numeric string to Engineering Notation
/// </summary>
/// <example>
/// class Program
/// {
///   static void Main(string[] args)
///   {
///     foreach(var a in SampleNumbers)
///     {
///        var leftPad = a < 0 ? "" : " ";
///        var rightPad = a < 0 ? "--> " : "-> ";
///        var original = $"{leftPad}{a.ToString().PadRight(22)}{rightPad}";
///        var engineering = $"{leftPad}{a.ToEngineeringNotation(256).PadRight(22)}{rightPad}";
///        var engineering3Figures = $"{leftPad}{a.ToEngineeringNotation(3)}";
///        Console.WriteLine($"/// {original}{engineering}{engineering3Figures}");
///     }
///     Console.ReadLine();
///   }
///     
///   private static IEnumerable<double> SampleNumbers
///   {
///     get
///     {
///       var testValues = new[]
///       {
///         Double.NaN,
///         Double.Epsilon,
///         Double.MinValue,
///         Double.MaxValue,
///         Double.NegativeInfinity,
///         Double.PositiveInfinity,
///         -300,
///         -30,
///         -1.1,
///         -1,
///         -0.1,
///         -0.01,
///         -0.001,
///         -0.0001,
///         0,
///         0.0001,
///         0.001,
///         0.01,
///         0.1,
///         1,
///         1.1,
///         30,
///         300
///       };
///  
///       foreach (double a in testValues)
///       {
///         yield return a;
///       }
///       for (int i = 28; i >= -28; --i)
///       {
///         yield return Math.Pow(10, i) * -9.995567890123;
///         yield return Math.Pow(10, i) * -1.234567890123;
///         yield return Math.Pow(10, i) * -1.235567890123;
///       }
///       for (int i = -28; i <= 28; ++i)
///       {
///         yield return Math.Pow(10, i) * 9.995567890123;
///         yield return Math.Pow(10, i) * 1.234567890123;
///         yield return Math.Pow(10, i) * 1.235567890123;
///       }
///     }
///   }
/// }
/// Gives the following output
/// 
///  NaN                   ->  NaN                   ->  NaN
///  5E-324                ->  5E-324                ->  5E-324
/// -1.7976931348623157E+308--> -179.76931348623157E+306--> -180E+306
///  1.7976931348623157E+308->  179.76931348623157E+306->  180E+306
/// -8                    --> -8                    --> -8
///  8                     ->  8                     ->  8
/// -300                  --> -300                  --> -300
/// -30                   --> -30                   --> -30
/// -1.1                  --> -1.1                  --> -1.1
/// -1                    --> -1                    --> -1
/// -0.1                  --> -100m                 --> -100m
/// -0.01                 --> -10m                  --> -10m
/// -0.001                --> -1m                   --> -1m
/// -0.0001               --> -100µ                 --> -100µ
///  0                     ->  0                     ->  0
///  0.0001                ->  100µ                  ->  100µ
///  0.001                 ->  1m                    ->  1m
///  0.01                  ->  10m                   ->  10m
///  0.1                   ->  100m                  ->  100m
///  1                     ->  1                     ->  1
///  1.1                   ->  1.1                   ->  1.1
///  30                    ->  30                    ->  30
///  300                   ->  300                   ->  300
/// -9.995567890123E+28   --> -99.95567890123E+27   --> -100E+27
/// -1.2345678901229999E+28--> -12.345678901229999E+27--> -12.3E+27
/// -1.235567890123E+28   --> -12.35567890123E+27   --> -12.4E+27
/// -9.995567890123E+27   --> -9.995567890123E+27   --> -10.0E+27
/// -1.234567890123E+27   --> -1.234567890123E+27   --> -1.23E+27
/// -1.2355678901230001E+27--> -1.2355678901230001E+27--> -1.24E+27
/// -9.995567890123001E+26--> -999.5567890123001Y   --> -1.00E+27
/// -1.234567890123E+26   --> -123.4567890123Y      --> -123Y
/// -1.2355678901230002E+26--> -123.55678901230002Y  --> -124Y
/// -9.995567890123001E+25--> -99.95567890123001Y   --> -100Y
/// -1.234567890123E+25   --> -12.34567890123Y      --> -12.3Y
/// -1.2355678901230002E+25--> -12.355678901230002Y  --> -12.4Y
/// -9.995567890123001E+24--> -9.995567890123001Y   --> -10.0Y
/// -1.234567890123E+24   --> -1.234567890123Y      --> -1.23Y
/// -1.235567890123E+24   --> -1.235567890123Y      --> -1.24Y
/// -9.995567890123001E+23--> -999.5567890123001Z   --> -1.00Y
/// -1.234567890123E+23   --> -123.4567890123Z      --> -123Z
/// -1.2355678901230002E+23--> -123.55678901230002Z  --> -124Z
/// -9.995567890123E+22   --> -99.95567890123Z      --> -100Z
/// -1.234567890123E+22   --> -12.34567890123Z      --> -12.3Z
/// -1.235567890123E+22   --> -12.35567890123Z      --> -12.4Z
/// -9.995567890123001E+21--> -9.995567890123001Z   --> -10.0Z
/// -1.2345678901229999E+21--> -1.2345678901229999Z  --> -1.23Z
/// -1.235567890123E+21   --> -1.235567890123Z      --> -1.24Z
/// -9.995567890123E+20   --> -999.5567890123E      --> -1.00Z
/// -1.2345678901229999E+20--> -123.45678901229999E  --> -123E
/// -1.235567890123E+20   --> -123.5567890123E      --> -124E
/// -9.995567890123001E+19--> -99.95567890123001E   --> -100E
/// -1.234567890123E+19   --> -12.34567890123E      --> -12.3E
/// -1.235567890123E+19   --> -12.35567890123E      --> -12.4E
/// -9.995567890123E+18   --> -9.995567890123E      --> -10.0E
/// -1.234567890123E+18   --> -1.234567890123E      --> -1.23E
/// -1.235567890123E+18   --> -1.235567890123E      --> -1.24E
/// -9.995567890123E+17   --> -999.5567890123P      --> -1.00E
/// -1.234567890123E+17   --> -123.4567890123P      --> -123P
/// -1.235567890123E+17   --> -123.5567890123P      --> -124P
/// -99955678901230000    --> -99.95567890123P      --> -100P
/// -12345678901230000    --> -12.34567890123P      --> -12.3P
/// -12355678901230000    --> -12.35567890123P      --> -12.4P
/// -9995567890123000     --> -9.995567890123P      --> -10.0P
/// -1234567890123000     --> -1.234567890123P      --> -1.23P
/// -1235567890123000     --> -1.235567890123P      --> -1.24P
/// -999556789012300      --> -999.5567890123T      --> -1.00P
/// -123456789012300      --> -123.4567890123T      --> -123T
/// -123556789012300      --> -123.5567890123T      --> -124T
/// -99955678901230       --> -99.95567890123T      --> -100T
/// -12345678901230       --> -12.34567890123T      --> -12.3T
/// -12355678901230       --> -12.35567890123T      --> -12.4T
/// -9995567890123        --> -9.995567890123T      --> -10.0T
/// -1234567890123        --> -1.234567890123T      --> -1.23T
/// -1235567890123        --> -1.235567890123T      --> -1.24T
/// -999556789012.3       --> -999.5567890123G      --> -1.00T
/// -123456789012.29999   --> -123.45678901229999G  --> -123G
/// -123556789012.3       --> -123.5567890123G      --> -124G
/// -99955678901.23001    --> -99.95567890123001G   --> -100G
/// -12345678901.23       --> -12.34567890123G      --> -12.3G
/// -12355678901.230001   --> -12.355678901230001G  --> -12.4G
/// -9995567890.123001    --> -9.995567890123001G   --> -10.0G
/// -1234567890.123       --> -1.234567890123G      --> -1.23G
/// -1235567890.1230001   --> -1.2355678901230001G  --> -1.24G
/// -999556789.0123       --> -999.5567890123M      --> -1.00G
/// -123456789.0123       --> -123.4567890123M      --> -123M
/// -123556789.0123       --> -123.5567890123M      --> -124M
/// -99955678.90123       --> -99.95567890123M      --> -100M
/// -12345678.90123       --> -12.34567890123M      --> -12.3M
/// -12355678.90123       --> -12.35567890123M      --> -12.4M
/// -9995567.890123       --> -9.995567890123M      --> -10.0M
/// -1234567.890123       --> -1.234567890123M      --> -1.23M
/// -1235567.8901230001   --> -1.2355678901230001M  --> -1.24M
/// -999556.7890123001    --> -999.5567890123001k   --> -1.00M
/// -123456.7890123       --> -123.4567890123k      --> -123k
/// -123556.78901230001   --> -123.55678901230001k  --> -124k
/// -99955.67890123       --> -99.95567890123k      --> -100k
/// -12345.67890123       --> -12.34567890123k      --> -12.3k
/// -12355.678901230001   --> -12.355678901230001k  --> -12.4k
/// -9995.567890123       --> -9.995567890123k      --> -10.0k
/// -1234.5678901229999   --> -1.2345678901229999k  --> -1.23k
/// -1235.567890123       --> -1.235567890123k      --> -1.24k
/// -999.5567890123001    --> -999.5567890123001    --> -1.00k
/// -123.45678901229999   --> -123.45678901229999   --> -123
/// -123.5567890123       --> -123.5567890123       --> -124
/// -99.95567890123       --> -99.95567890123       --> -100
/// -12.345678901229999   --> -12.345678901229999   --> -12.3
/// -12.35567890123       --> -12.35567890123       --> -12.4
/// -9.995567890123       --> -9.995567890123       --> -10.0
/// -1.234567890123       --> -1.234567890123       --> -1.23
/// -1.235567890123       --> -1.235567890123       --> -1.24
/// -0.9995567890123      --> -999.5567890123m      --> -1.00
/// -0.1234567890123      --> -123.4567890123m      --> -123m
/// -0.12355678901230001  --> -123.55678901230001m  --> -124m
/// -0.09995567890123001  --> -99.95567890123001m   --> -100m
/// -0.01234567890123     --> -12.34567890123m      --> -12.3m
/// -0.01235567890123     --> -12.35567890123m      --> -12.4m
/// -0.009995567890123    --> -9.995567890123m      --> -10.0m
/// -0.001234567890123    --> -1.234567890123m      --> -1.23m
/// -0.0012355678901230002--> -1.2355678901230002m  --> -1.24m
/// -0.0009995567890123001--> -999.5567890123001µ   --> -1.00m
/// -0.0001234567890123   --> -123.4567890123µ      --> -123µ
/// -0.0001235567890123   --> -123.5567890123µ      --> -124µ
/// -9.995567890123001E-05--> -99.95567890123001µ   --> -100µ
/// -1.234567890123E-05   --> -12.34567890123µ      --> -12.3µ
/// -1.2355678901230002E-05--> -12.355678901230002µ  --> -12.4µ
/// -9.995567890123E-06   --> -9.995567890123µ      --> -10.0µ
/// -1.234567890123E-06   --> -1.234567890123µ      --> -1.23µ
/// -1.235567890123E-06   --> -1.235567890123µ      --> -1.24µ
/// -9.995567890123E-07   --> -999.5567890123n      --> -1.00µ
/// -1.234567890123E-07   --> -123.4567890123n      --> -123n
/// -1.235567890123E-07   --> -123.5567890123n      --> -124n
/// -9.995567890123E-08   --> -99.95567890123n      --> -100n
/// -1.234567890123E-08   --> -12.34567890123n      --> -12.3n
/// -1.2355678901230001E-08--> -12.355678901230001n  --> -12.4n
/// -9.995567890123E-09   --> -9.995567890123n      --> -10.0n
/// -1.234567890123E-09   --> -1.234567890123n      --> -1.23n
/// -1.2355678901230001E-09--> -1.2355678901230001n  --> -1.24n
/// -9.995567890123E-10   --> -999.5567890123p      --> -1.00n
/// -1.234567890123E-10   --> -123.4567890123p      --> -123p
/// -1.235567890123E-10   --> -123.5567890123p      --> -124p
/// -9.995567890123E-11   --> -99.95567890123p      --> -100p
/// -1.2345678901229998E-11--> -12.345678901229998p  --> -12.3p
/// -1.235567890123E-11   --> -12.35567890123p      --> -12.4p
/// -9.995567890123E-12   --> -9.995567890123p      --> -10.0p
/// -1.2345678901229999E-12--> -1.2345678901229999p  --> -1.23p
/// -1.235567890123E-12   --> -1.235567890123p      --> -1.24p
/// -9.995567890123E-13   --> -999.5567890123f      --> -1.00p
/// -1.234567890123E-13   --> -123.4567890123f      --> -123f
/// -1.2355678901230002E-13--> -123.55678901230002f  --> -124f
/// -9.995567890123001E-14--> -99.95567890123001f   --> -100f
/// -1.2345678901229999E-14--> -12.345678901229999f  --> -12.3f
/// -1.235567890123E-14   --> -12.35567890123f      --> -12.4f
/// -9.995567890123002E-15--> -9.995567890123002f   --> -10.0f
/// -1.234567890123E-15   --> -1.234567890123f      --> -1.23f
/// -1.2355678901230002E-15--> -1.2355678901230002f  --> -1.24f
/// -9.995567890123E-16   --> -999.5567890123a      --> -1.00f
/// -1.234567890123E-16   --> -123.4567890123a      --> -123a
/// -1.2355678901230001E-16--> -123.55678901230001a  --> -124a
/// -9.995567890123001E-17--> -99.95567890123001a   --> -100a
/// -1.234567890123E-17   --> -12.34567890123a      --> -12.3a
/// -1.2355678901230001E-17--> -12.355678901230001a  --> -12.4a
/// -9.995567890123002E-18--> -9.995567890123002a   --> -10.0a
/// -1.234567890123E-18   --> -1.234567890123a      --> -1.23a
/// -1.2355678901230002E-18--> -1.2355678901230002a  --> -1.24a
/// -9.995567890123E-19   --> -999.5567890123z      --> -1.00a
/// -1.2345678901229999E-19--> -123.45678901229999z  --> -123z
/// -1.235567890123E-19   --> -123.5567890123z      --> -124z
/// -9.995567890123E-20   --> -99.95567890123z      --> -100z
/// -1.2345678901229999E-20--> -12.345678901229999z  --> -12.3z
/// -1.235567890123E-20   --> -12.35567890123z      --> -12.4z
/// -9.995567890122999E-21--> -9.995567890122999z   --> -10.0z
/// -1.2345678901229998E-21--> -1.2345678901229998z  --> -1.23z
/// -1.2355678901229999E-21--> -1.2355678901229999z  --> -1.24z
/// -9.995567890123002E-22--> -999.5567890123002y   --> -1.00z
/// -1.234567890123E-22   --> -123.4567890123y      --> -123y
/// -1.235567890123E-22   --> -123.5567890123y      --> -124y
/// -9.995567890123E-23   --> -99.95567890123y      --> -100y
/// -1.2345678901229999E-23--> -12.345678901229999y  --> -12.3y
/// -1.235567890123E-23   --> -12.35567890123y      --> -12.4y
/// -9.995567890123E-24   --> -9.995567890123y      --> -10.0y
/// -1.234567890123E-24   --> -1.234567890123y      --> -1.23y
/// -1.235567890123E-24   --> -1.235567890123y      --> -1.24y
/// -9.995567890123E-25   --> -999.5567890123E-27   --> -1.00y
/// -1.234567890123E-25   --> -123.4567890123E-27   --> -123E-27
/// -1.2355678901230002E-25--> -123.55678901230002E-27--> -124E-27
/// -9.995567890123E-26   --> -99.95567890123E-27   --> -100E-27
/// -1.234567890123E-26   --> -12.34567890123E-27   --> -12.3E-27
/// -1.2355678901230001E-26--> -12.355678901230001E-27--> -12.4E-27
/// -9.995567890123001E-27--> -9.995567890123001E-27--> -10.0E-27
/// -1.2345678901229999E-27--> -1.2345678901229999E-27--> -1.23E-27
/// -1.2355678901230001E-27--> -1.2355678901230001E-27--> -1.24E-27
/// -9.995567890123E-28   --> -999.5567890123E-30   --> -1.00E-27
/// -1.2345678901229998E-28--> -123.45678901229998E-30--> -123E-30
/// -1.235567890123E-28   --> -123.5567890123E-30   --> -124E-30
///  9.995567890123E-28    ->  999.5567890123E-30    ->  1.00E-27
///  1.2345678901229998E-28->  123.45678901229998E-30->  123E-30
///  1.235567890123E-28    ->  123.5567890123E-30    ->  124E-30
///  9.995567890123001E-27 ->  9.995567890123001E-27 ->  10.0E-27
///  1.2345678901229999E-27->  1.2345678901229999E-27->  1.23E-27
///  1.2355678901230001E-27->  1.2355678901230001E-27->  1.24E-27
///  9.995567890123E-26    ->  99.95567890123E-27    ->  100E-27
///  1.234567890123E-26    ->  12.34567890123E-27    ->  12.3E-27
///  1.2355678901230001E-26->  12.355678901230001E-27->  12.4E-27
///  9.995567890123E-25    ->  999.5567890123E-27    ->  1.00y
///  1.234567890123E-25    ->  123.4567890123E-27    ->  123E-27
///  1.2355678901230002E-25->  123.55678901230002E-27->  124E-27
///  9.995567890123E-24    ->  9.995567890123y       ->  10.0y
///  1.234567890123E-24    ->  1.234567890123y       ->  1.23y
///  1.235567890123E-24    ->  1.235567890123y       ->  1.24y
///  9.995567890123E-23    ->  99.95567890123y       ->  100y
///  1.2345678901229999E-23->  12.345678901229999y   ->  12.3y
///  1.235567890123E-23    ->  12.35567890123y       ->  12.4y
///  9.995567890123002E-22 ->  999.5567890123002y    ->  1.00z
///  1.234567890123E-22    ->  123.4567890123y       ->  123y
///  1.235567890123E-22    ->  123.5567890123y       ->  124y
///  9.995567890122999E-21 ->  9.995567890122999z    ->  10.0z
///  1.2345678901229998E-21->  1.2345678901229998z   ->  1.23z
///  1.2355678901229999E-21->  1.2355678901229999z   ->  1.24z
///  9.995567890123E-20    ->  99.95567890123z       ->  100z
///  1.2345678901229999E-20->  12.345678901229999z   ->  12.3z
///  1.235567890123E-20    ->  12.35567890123z       ->  12.4z
///  9.995567890123E-19    ->  999.5567890123z       ->  1.00a
///  1.2345678901229999E-19->  123.45678901229999z   ->  123z
///  1.235567890123E-19    ->  123.5567890123z       ->  124z
///  9.995567890123002E-18 ->  9.995567890123002a    ->  10.0a
///  1.234567890123E-18    ->  1.234567890123a       ->  1.23a
///  1.2355678901230002E-18->  1.2355678901230002a   ->  1.24a
///  9.995567890123001E-17 ->  99.95567890123001a    ->  100a
///  1.234567890123E-17    ->  12.34567890123a       ->  12.3a
///  1.2355678901230001E-17->  12.355678901230001a   ->  12.4a
///  9.995567890123E-16    ->  999.5567890123a       ->  1.00f
///  1.234567890123E-16    ->  123.4567890123a       ->  123a
///  1.2355678901230001E-16->  123.55678901230001a   ->  124a
///  9.995567890123002E-15 ->  9.995567890123002f    ->  10.0f
///  1.234567890123E-15    ->  1.234567890123f       ->  1.23f
///  1.2355678901230002E-15->  1.2355678901230002f   ->  1.24f
///  9.995567890123001E-14 ->  99.95567890123001f    ->  100f
///  1.2345678901229999E-14->  12.345678901229999f   ->  12.3f
///  1.235567890123E-14    ->  12.35567890123f       ->  12.4f
///  9.995567890123E-13    ->  999.5567890123f       ->  1.00p
///  1.234567890123E-13    ->  123.4567890123f       ->  123f
///  1.2355678901230002E-13->  123.55678901230002f   ->  124f
///  9.995567890123E-12    ->  9.995567890123p       ->  10.0p
///  1.2345678901229999E-12->  1.2345678901229999p   ->  1.23p
///  1.235567890123E-12    ->  1.235567890123p       ->  1.24p
///  9.995567890123E-11    ->  99.95567890123p       ->  100p
///  1.2345678901229998E-11->  12.345678901229998p   ->  12.3p
///  1.235567890123E-11    ->  12.35567890123p       ->  12.4p
///  9.995567890123E-10    ->  999.5567890123p       ->  1.00n
///  1.234567890123E-10    ->  123.4567890123p       ->  123p
///  1.235567890123E-10    ->  123.5567890123p       ->  124p
///  9.995567890123E-09    ->  9.995567890123n       ->  10.0n
///  1.234567890123E-09    ->  1.234567890123n       ->  1.23n
///  1.2355678901230001E-09->  1.2355678901230001n   ->  1.24n
///  9.995567890123E-08    ->  99.95567890123n       ->  100n
///  1.234567890123E-08    ->  12.34567890123n       ->  12.3n
///  1.2355678901230001E-08->  12.355678901230001n   ->  12.4n
///  9.995567890123E-07    ->  999.5567890123n       ->  1.00µ
///  1.234567890123E-07    ->  123.4567890123n       ->  123n
///  1.235567890123E-07    ->  123.5567890123n       ->  124n
///  9.995567890123E-06    ->  9.995567890123µ       ->  10.0µ
///  1.234567890123E-06    ->  1.234567890123µ       ->  1.23µ
///  1.235567890123E-06    ->  1.235567890123µ       ->  1.24µ
///  9.995567890123001E-05 ->  99.95567890123001µ    ->  100µ
///  1.234567890123E-05    ->  12.34567890123µ       ->  12.3µ
///  1.2355678901230002E-05->  12.355678901230002µ   ->  12.4µ
///  0.0009995567890123001 ->  999.5567890123001µ    ->  1.00m
///  0.0001234567890123    ->  123.4567890123µ       ->  123µ
///  0.0001235567890123    ->  123.5567890123µ       ->  124µ
///  0.009995567890123     ->  9.995567890123m       ->  10.0m
///  0.001234567890123     ->  1.234567890123m       ->  1.23m
///  0.0012355678901230002 ->  1.2355678901230002m   ->  1.24m
///  0.09995567890123001   ->  99.95567890123001m    ->  100m
///  0.01234567890123      ->  12.34567890123m       ->  12.3m
///  0.01235567890123      ->  12.35567890123m       ->  12.4m
///  0.9995567890123       ->  999.5567890123m       ->  1.00
///  0.1234567890123       ->  123.4567890123m       ->  123m
///  0.12355678901230001   ->  123.55678901230001m   ->  124m
///  9.995567890123        ->  9.995567890123        ->  10.0
///  1.234567890123        ->  1.234567890123        ->  1.23
///  1.235567890123        ->  1.235567890123        ->  1.24
///  99.95567890123        ->  99.95567890123        ->  100
///  12.345678901229999    ->  12.345678901229999    ->  12.3
///  12.35567890123        ->  12.35567890123        ->  12.4
///  999.5567890123001     ->  999.5567890123001     ->  1.00k
///  123.45678901229999    ->  123.45678901229999    ->  123
///  123.5567890123        ->  123.5567890123        ->  124
///  9995.567890123        ->  9.995567890123k       ->  10.0k
///  1234.5678901229999    ->  1.2345678901229999k   ->  1.23k
///  1235.567890123        ->  1.235567890123k       ->  1.24k
///  99955.67890123        ->  99.95567890123k       ->  100k
///  12345.67890123        ->  12.34567890123k       ->  12.3k
///  12355.678901230001    ->  12.355678901230001k   ->  12.4k
///  999556.7890123001     ->  999.5567890123001k    ->  1.00M
///  123456.7890123        ->  123.4567890123k       ->  123k
///  123556.78901230001    ->  123.55678901230001k   ->  124k
///  9995567.890123        ->  9.995567890123M       ->  10.0M
///  1234567.890123        ->  1.234567890123M       ->  1.23M
///  1235567.8901230001    ->  1.2355678901230001M   ->  1.24M
///  99955678.90123        ->  99.95567890123M       ->  100M
///  12345678.90123        ->  12.34567890123M       ->  12.3M
///  12355678.90123        ->  12.35567890123M       ->  12.4M
///  999556789.0123        ->  999.5567890123M       ->  1.00G
///  123456789.0123        ->  123.4567890123M       ->  123M
///  123556789.0123        ->  123.5567890123M       ->  124M
///  9995567890.123001     ->  9.995567890123001G    ->  10.0G
///  1234567890.123        ->  1.234567890123G       ->  1.23G
///  1235567890.1230001    ->  1.2355678901230001G   ->  1.24G
///  99955678901.23001     ->  99.95567890123001G    ->  100G
///  12345678901.23        ->  12.34567890123G       ->  12.3G
///  12355678901.230001    ->  12.355678901230001G   ->  12.4G
///  999556789012.3        ->  999.5567890123G       ->  1.00T
///  123456789012.29999    ->  123.45678901229999G   ->  123G
///  123556789012.3        ->  123.5567890123G       ->  124G
///  9995567890123         ->  9.995567890123T       ->  10.0T
///  1234567890123         ->  1.234567890123T       ->  1.23T
///  1235567890123         ->  1.235567890123T       ->  1.24T
///  99955678901230        ->  99.95567890123T       ->  100T
///  12345678901230        ->  12.34567890123T       ->  12.3T
///  12355678901230        ->  12.35567890123T       ->  12.4T
///  999556789012300       ->  999.5567890123T       ->  1.00P
///  123456789012300       ->  123.4567890123T       ->  123T
///  123556789012300       ->  123.5567890123T       ->  124T
///  9995567890123000      ->  9.995567890123P       ->  10.0P
///  1234567890123000      ->  1.234567890123P       ->  1.23P
///  1235567890123000      ->  1.235567890123P       ->  1.24P
///  99955678901230000     ->  99.95567890123P       ->  100P
///  12345678901230000     ->  12.34567890123P       ->  12.3P
///  12355678901230000     ->  12.35567890123P       ->  12.4P
///  9.995567890123E+17    ->  999.5567890123P       ->  1.00E
///  1.234567890123E+17    ->  123.4567890123P       ->  123P
///  1.235567890123E+17    ->  123.5567890123P       ->  124P
///  9.995567890123E+18    ->  9.995567890123E       ->  10.0E
///  1.234567890123E+18    ->  1.234567890123E       ->  1.23E
///  1.235567890123E+18    ->  1.235567890123E       ->  1.24E
///  9.995567890123001E+19 ->  99.95567890123001E    ->  100E
///  1.234567890123E+19    ->  12.34567890123E
Oregano answered 5/2, 2018 at 5:48 Comment(0)
D
1

Use my Format method as follows:

Engineering.Format(1.5e-4, 3, true); // Returns "150µ"

Table of example values below after the code.

public static class Engineering
{
    static Engineering()
    {
        System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
        DecimalSeparator = ci.NumberFormat.NumberDecimalSeparator;
    }

    static readonly string DecimalSeparator;
    const string ExponentFormat = "'E'+0;'E'-0;''"; // Format sections pos;neg;zero

    const string SIPrefixesSmall = "mµnpfa";
    const string SIPrefixesLarge = "kMGTPE";

    /// <summary>
    /// Format a double using engineering notation (the exponent will be a multiple of 3.)
    /// </summary>
    public static string Format(double value, int digits, bool useSIprefixes)
    {
        if (double.IsNaN(value) ||
            double.IsInfinity(value))
        {
            return value.ToString();
        }

        if (digits < 1)
        {
            throw new ArgumentException("The digits parameter must be greater than zero.");
        }

        if (value == 0d)
        {
            return 0d.ToString($"F{digits - 1}") + FormatExponent(useSIprefixes, 0);
        }

        string sign = "";

        if (value < 0d)
        {
            sign = "-";
            value = -value;
        }

        // Custom exponential formatting using '#' will give us exactly our digits plus an exponent
        string scientific = value.ToString(new string('#', digits) + "E0");
        string significand = scientific.Remove(digits);
        int exponent = int.Parse(scientific.Substring(digits + 1));
        // (significand now already contains the requested number of digits with no decimal separator in it)

        // Round the exponent to a multiple of three in the negative direction (towards -inf)
        int r = exponent < 0 ? -2 : 0;
        int exponent2 = (exponent + r) / 3 * 3;
        int digits2 = digits + exponent - exponent2;
        
        // Decide on the number of digits before the decimal
        int before = digits2 % 3;
        if (before == 0) before = 3;
        exponent2 += digits2 - before;
        
        // Decimal placement and final formatting
        string s = significand;
        if (before > digits) s += new string('0', before - digits);
        if (before < digits2) s = s.Insert(before, DecimalSeparator);
        return sign + s + FormatExponent(useSIprefixes, exponent2);
    }

    static string FormatExponent(bool useSIPrefixes, int e)
    {
        if (useSIPrefixes)
        {
            int i = Math.Abs(e) / 3 - 1;
            if (e > 0 && i < SIPrefixesLarge.Length) return SIPrefixesLarge[i].ToString();
            if (e < 0 && i < SIPrefixesSmall.Length) return SIPrefixesSmall[i].ToString();
        }

        return e.ToString(ExponentFormat);
    }
}

Table of example values:

value               digits:        1 (exp.)      1             2             3             4                6
=============================================================================================================
0                                  0             0           0.0          0.00         0.000          0.00000
1                                  1             1           1.0          1.00         1.000          1.00000
10                                10            10            10          10.0         10.00          10.0000
100                              100           100           100           100         100.0          100.000
1000                            1E+3            1k          1.0k         1.00k        1.000k         1.00000k
10000                          10E+3           10k           10k         10.0k        10.00k         10.0000k
100000                        100E+3          100k          100k          100k        100.0k         100.000k
1000000                         1E+6            1M          1.0M         1.00M        1.000M         1.00000M
10000000                       10E+6           10M           10M         10.0M        10.00M         10.0000M
100000000                     100E+6          100M          100M          100M        100.0M         100.000M
1000000000                      1E+9            1G          1.0G         1.00G        1.000G         1.00000G
0.1                           100E-3          100m          100m          100m        100.0m         100.000m
0.01                           10E-3           10m           10m         10.0m        10.00m         10.0000m
0.001                           1E-3            1m          1.0m         1.00m        1.000m         1.00000m
0.0001                        100E-6          100µ          100µ          100µ        100.0µ         100.000µ
1E-05                          10E-6           10µ           10µ         10.0µ        10.00µ         10.0000µ
1E-06                           1E-6            1µ          1.0µ         1.00µ        1.000µ         1.00000µ
1E-07                         100E-9          100n          100n          100n        100.0n         100.000n
1E-08                          10E-9           10n           10n         10.0n        10.00n         10.0000n
1E-09                           1E-9            1n          1.0n         1.00n        1.000n         1.00000n
1E-10                        100E-12          100p          100p          100p        100.0p         100.000p
0.086                          90E-3           90m           86m         86.0m        86.00m         86.0000m
0.00030908                    300E-6          300µ          310µ          309µ        309.1µ         309.080µ
1239451                         1E+6            1M          1.2M         1.24M        1.239M         1.23945M
5084611353                      5E+9            5G          5.1G         5.08G        5.085G         5.08461G
8.46113537656557E-18           8E-18            8a          8.5a         8.46a        8.461a         8.46114a
50.8437                           50            50            51          50.8         50.84          50.8437
50.846                            50            50            51          50.8         50.85          50.8460
990                             1E+3            1k           990           990         990.0          990.000
1500                            2E+3            2k          1.5k         1.50k        1.500k         1.50000k
1490                            1E+3            1k          1.5k         1.49k        1.490k         1.49000k
-990                           -1E+3           -1k          -990          -990        -990.0         -990.000
-1500                          -2E+3           -2k         -1.5k        -1.50k       -1.500k        -1.50000k
-1490                          -1E+3           -1k         -1.5k        -1.49k       -1.490k        -1.49000k
-5488                          -5E+3           -5k         -5.5k        -5.49k       -5.488k        -5.48800k
7.89E-05                       80E-6           80µ           79µ         78.9µ        78.90µ         78.9000µ
50.84611353765656                 50            50            51          50.8         50.85          50.8461
0.073699979                    70E-3           70m           74m         73.7m        73.70m         73.7000m
0.8                           800E-3          800m          800m          800m        800.0m         800.000m
0.999                              1             1           1.0          999m        999.0m         999.000m
0.111                         100E-3          100m          110m          111m        111.0m         111.000m
0.111111                      100E-3          100m          110m          111m        111.1m         111.111m
NaN                              NaN           NaN           NaN           NaN           NaN              NaN
∞                                  ∞             ∞             ∞             ∞             ∞                ∞
-∞                                -∞            -∞            -∞            -∞            -∞               -∞
=============================================================================================================
                                   1 (exp.)      1             2             3             4                6
Doorframe answered 14/4, 2023 at 18:37 Comment(0)
O
0

This is an old thread, but the answer might as well be correct. Issues with the existing code: it doesn't handle NaN, any of the infinities, negative numbers, or very small number (like double.Epsilon). And you can't pass in a precision.

My code is:

    static string DoubleToEngineering(double value, string displayPrecision)
    {
        string Retval;
        if (double.IsNaN(value)
            || double.IsInfinity(value)
            || double.IsNegativeInfinity(value)
            || double.IsPositiveInfinity(value)
            || value == 0.0
            )
        {
            Retval  = String.Format("{0:" + "F" + displayPrecision + "}", value);
            return Retval;
        }
        bool isNeg = value < 0;
        if (isNeg) value = -value;

        int exp = (int)(Math.Floor(Math.Log10(value) / 3.0) * 3.0);
        int powerToRaise = -exp;
        double newValue = value;
        // Problem: epsilon is something-324
        // The biggest possible number is somethinge306
        // You simply can't do a Math.Power (10, 324), it becomes infiniity.
        if (powerToRaise > 300)
        {
            powerToRaise -= 300;
            newValue = newValue * Math.Pow(10.0, 300);
        }

        newValue = newValue * Math.Pow(10.0, powerToRaise);

        // I don't know when this below is triggered.
        if (newValue >= 1000.0)
        {
            newValue = newValue / 1000.0;
            exp = exp + 3;
        }
        var fmt = "{0:F" + displayPrecision + "}";
        Retval = String.Format (fmt, newValue);
        if (exp != 0) Retval += String.Format("e{0}", exp);
        if (isNeg) Retval = "-" + Retval;
        return Retval;
    }

Test cases are below. My personal standard for test cases (sorry, this doesn't follow the latest and best NUnit guidance): the public static Test() takes no parameters and return the number of errors. It normally calls a private static TestOne(args, expected) which calculates the actual value, compared to the expected value, and returns the number of errors.

   private static int TestDoubleToEngineeringOne(double value, string expected)
    {
        var fakePrecision = "4";
        int NError = 0;
        var actual = DoubleToEngineering(value, fakePrecision);
        if (actual != expected)
        {
            System.Diagnostics.Debug.WriteLine($"ERROR: DoubleToEngineering({value}) expected {expected} actual {actual}");
            NError++;
        }
        return NError;
    }

    public static int TestDoubleToEngineering()
    {
        int NError = 0;
        NError += TestDoubleToEngineeringOne(0, "0.0000");
        NError += TestDoubleToEngineeringOne(1, "1.0000");
        NError += TestDoubleToEngineeringOne(2, "2.0000");
        NError += TestDoubleToEngineeringOne(3, "3.0000");
        NError += TestDoubleToEngineeringOne(10, "10.0000");
        NError += TestDoubleToEngineeringOne(999, "999.0000");
        NError += TestDoubleToEngineeringOne(1000, "1.0000e3");

        NError += TestDoubleToEngineeringOne(1.234E21, "1.2340e21");

        NError += TestDoubleToEngineeringOne(-1, "-1.0000");
        NError += TestDoubleToEngineeringOne(-999, "-999.0000");
        NError += TestDoubleToEngineeringOne(-1000, "-1.0000e3");


        NError += TestDoubleToEngineeringOne(0.1, "100.0000e-3");
        NError += TestDoubleToEngineeringOne(0.02, "20.0000e-3");
        NError += TestDoubleToEngineeringOne(0.003, "3.0000e-3");
        NError += TestDoubleToEngineeringOne(0.0004, "400.0000e-6");
        NError += TestDoubleToEngineeringOne(0.00005, "50.0000e-6");

        NError += TestDoubleToEngineeringOne(double.NaN, "NaN");
        NError += TestDoubleToEngineeringOne(double.PositiveInfinity, "∞");
        NError += TestDoubleToEngineeringOne(double.NegativeInfinity, "-∞");
        NError += TestDoubleToEngineeringOne(double.Epsilon, "4.9407e-324");
        NError += TestDoubleToEngineeringOne(double.MaxValue, "179.7693e306");
        NError += TestDoubleToEngineeringOne(double.MinValue, "-179.7693e306");

        return NError;
    }
Operate answered 26/9, 2017 at 4:11 Comment(0)
I
0

ICustomFormmatter using a private dictionary for the symbols.

class EngNotationFormatter : IFormatProvider, ICustomFormatter
{
    private readonly Dictionary<double, string> notationSymbols = new Dictionary<double, string>
    {
        {double.NegativeInfinity, ""}, //Handles when value is 0
        {-24, "y"},
        {-21, "z"},
        {-18, "a"},
        {-15, "f"},
        {-12, "p"},
        {-9, "n"},
        {-6, "μ"},
        {-3, "m"},
        {0, ""},
        {3, "k"},
        {6, "M"},
        {9, "G"},
        {12, "T"},
        {15, "P"},
        {18, "E"},
        {21, "Z"},
        {24, "Y"},
    };

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        double value = Convert.ToDouble(arg);
        
        double exponent = Math.Log10(Math.Abs(value));
        double engExponent = Math.Floor(exponent / 3) * 3;

        string symbol = notationSymbols.ContainsKey(engExponent) ? notationSymbols[engExponent] : "e" + engExponent;

        return (value * Math.Pow(10, (int)-engExponent)) + symbol;
    }

    public object GetFormat(Type formatType)
    {
        if (formatType == typeof(ICustomFormatter))
            return this;
        else
            return null;
    }
}

Example use

(0.00005678).ToString(new EngNotationFormatter()); //56.78μ
(0.1234).ToString(new EngNotationFormatter());     //123.4m
(0).ToString(new EngNotationFormatter());          //0
(1300).ToString(new EngNotationFormatter());       //1.3k
(19000).ToString(new EngNotationFormatter());      //19k
Interlaminate answered 18/7, 2020 at 1:4 Comment(0)
P
0

Here is a method:

public static string GetNumberWithUnitPrefix(double number, int power = 1)
    {
        char[] incPrefixes = new[] { 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' };
        char[] decPrefixes = new[] { 'm', 'µ', 'n', 'p', 'f', 'a', 'z', 'y' };

        int degree = (int)Math.Floor(Math.Log10(Math.Abs(number)) / (3 * (double)power));
        double scaled = number * Math.Pow(1000, -(degree * power));

        char? prefix = null;
        switch (Math.Sign(degree))
        {
            case 1: prefix = incPrefixes[degree - 1]; break;
            case -1: prefix = decPrefixes[-degree - 1]; break;
        }

        return ToStringWithSeparator(MathFunctions.RoundToSignificantDigits(scaled, 4)).ToString() + prefix;
    }

use the power input (in this case 2) if you want to convert m² to mm² for example

(improved answer form Formatting a number with a metric prefix?)

Preeminent answered 12/2, 2021 at 11:1 Comment(0)
A
-2

To solve this problem, you want to create a class (call it Engineering) which inherits from Float on which you override the ToString() member.

Edit: Okay, I understand the issue now. Still, the solution is subclassing.

Averse answered 30/4, 2009 at 17:47 Comment(5)
No, it's engineering notation.Afterburner
I don't think the reference is to distance necessarily. It just happened that he used an example with "m" which could be, say, milliseconds (ms), millimeters (mm), milliamps (mA), etc.Fructose
The question is not about distances, it's about engineering notation for numbers; 1 mili = 0.001, 1 micro = 0.000001, 1 kilo = 1000, etc.Bine
Gotcha; I think I was most confused by the "mu" symbol, which I have learned to read as "micron". :-)Averse
Structs cannot be subclassed. A good approach is to do what highlycaffeinated said: Implement a formatter. Implement an extension method that returns a formatted string is also a good one.Cogitation

© 2022 - 2024 — McMap. All rights reserved.