代码之家  ›  专栏  ›  技术社区  ›  Nick

C?中的工程符号

  •  11
  • Nick  · 技术社区  · 16 年前

    是否有任何代码(或内置函数)允许在工程符号中输出浮点数?

    例如, 1.5e-4 将显示为 150µ 5e-3显示为 5m

    8 回复  |  直到 7 年前
        1
  •  10
  •   Patrick McDonald    15 年前

    这可能需要重构:

    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";
        }
    }
    
        2
  •  8
  •   tvanfosson    16 年前

    这里有一个 link 对于一些做类似事情的ruby代码,尽管它的格式是dddem,其中m,指数,总是3的倍数。

    音译成c。因为我不熟悉格式,所以我不确定这是否符合您的要求。例如,0.0015格式为2E-3。使用case语句和utf-8或其他编码将指数替换为希腊字母是相当简单的。这个练习留给读者。

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

    使用:

    Console.WriteLine( ((double)15000).ToEngineering() );
    double val = 15000;
    Console.WriteLine( val.ToEngineering() );
    
        3
  •  6
  •   highlycaffeinated    16 年前

    与其子类化,不如利用double实现了iformattable,并编写了一个iformatprovider来格式化数字。然后我会得到类似的代码:

    double d = 123.45;
    Console.WriteLine(d.ToString(null, new MyCustomFormat()));
    
        4
  •  1
  •   ovejka    8 年前

    把前面的两个答案组合起来,再加上一个单位(伏特,等等)就可以得到很好的答案,比如11000伏特等于11伏特。

    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);
    }
    
        5
  •  1
  •   John Stewien    7 年前

    我来到这里寻找一个函数,可以用任何数字表示,例如有符号/无符号的int,浮点,双,十进制,数字字符串,当我发现一些灵感的Patrick McDonald的答案时,我没有找到我要找的答案,因此,我编写了自己的解决方案,它采用了一个数字字符串,它可以从任何数字类型中容易地获得。我将在此线程中分享我的解决方案,供其他人使用,如果他们希望有更通用的解决方案:

    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;
    
      // work out how much we need to shift the decimal point to get
      // engineering notation
    
      var decimalShiftRequired = exponent % 3;
      if (decimalShiftRequired < 0)
        decimalShiftRequired += 3;
    
      // 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)
      {
        str = str.Substring(0, significantFigures.Value);
      }
      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}";
    }
    

    这是位于上面函数顶部的注释块,我把它放在最后,这样人们就不必滚动它来获得代码:

    /// <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) * -1.234567890123;
    ///       }
    ///       for (int i = -28; i <= 28; ++i)
    ///       {
    ///         yield return Math.Pow(10, i) * 1.234567890123;
    ///       }
    ///     }
    ///   }
    /// }
    /// Gives the following output
    /// 
    ///  NaN                   ->  NaN                   ->  NaN
    ///  4.94065645841247E-324 ->  4.94065645841247E-324 ->  4.94E-324
    /// -1.79769313486232E+308--> -179.769313486232E+306--> -179E+306
    ///  1.79769313486232E+308 ->  179.769313486232E+306 ->  179E+306
    /// -Infinity             --> -Infinity             --> -Infinity
    ///  Infinity              ->  Infinity              ->  Infinity
    /// -30000                --> -30k                  --> -30k
    /// -3000                 --> -3k                   --> -3k
    /// -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
    ///  3000                  ->  3k                    ->  3k
    ///  30000                 ->  30k                   ->  30k
    /// -1.234567890123E+28   --> -12.34567890123E+27   --> -12.3E+27
    /// -1.234567890123E+27   --> -1.234567890123E+27   --> -1.23E+27
    /// -1.234567890123E+26   --> -123.4567890123Y      --> -123Y
    /// -1.234567890123E+25   --> -12.34567890123Y      --> -12.3Y
    /// -1.234567890123E+24   --> -1.234567890123Y      --> -1.23Y
    /// -1.234567890123E+23   --> -123.4567890123Z      --> -123Z
    /// -1.234567890123E+22   --> -12.34567890123Z      --> -12.3Z
    /// -1.234567890123E+21   --> -1.234567890123Z      --> -1.23Z
    /// -1.234567890123E+20   --> -123.4567890123E      --> -123E
    /// -1.234567890123E+19   --> -12.34567890123E      --> -12.3E
    /// -1.234567890123E+18   --> -1.234567890123E      --> -1.23E
    /// -1.234567890123E+17   --> -123.4567890123P      --> -123P
    /// -1.234567890123E+16   --> -12.34567890123P      --> -12.3P
    /// -1.234567890123E+15   --> -1.234567890123P      --> -1.23P
    /// -123456789012300      --> -123.4567890123T      --> -123T
    /// -12345678901230       --> -12.34567890123T      --> -12.3T
    /// -1234567890123        --> -1.234567890123T      --> -1.23T
    /// -123456789012.3       --> -123.4567890123G      --> -123G
    /// -12345678901.23       --> -12.34567890123G      --> -12.3G
    /// -1234567890.123       --> -1.234567890123G      --> -1.23G
    /// -123456789.0123       --> -123.4567890123M      --> -123M
    /// -12345678.90123       --> -12.34567890123M      --> -12.3M
    /// -1234567.890123       --> -1.234567890123M      --> -1.23M
    /// -123456.7890123       --> -123.4567890123k      --> -123k
    /// -12345.67890123       --> -12.34567890123k      --> -12.3k
    /// -1234.567890123       --> -1.234567890123k      --> -1.23k
    /// -123.4567890123       --> -123.4567890123       --> -123
    /// -12.34567890123       --> -12.34567890123       --> -12.3
    /// -1.234567890123       --> -1.234567890123       --> -1.23
    /// -0.1234567890123      --> -123.4567890123m      --> -123m
    /// -0.01234567890123     --> -12.34567890123m      --> -12.3m
    /// -0.001234567890123    --> -1.234567890123m      --> -1.23m
    /// -0.0001234567890123   --> -123.4567890123μ      --> -123μ
    /// -1.234567890123E-05   --> -12.34567890123μ      --> -12.3μ
    /// -1.234567890123E-06   --> -1.234567890123μ      --> -1.23μ
    /// -1.234567890123E-07   --> -123.4567890123n      --> -123n
    /// -1.234567890123E-08   --> -12.34567890123n      --> -12.3n
    /// -1.234567890123E-09   --> -1.234567890123n      --> -1.23n
    /// -1.234567890123E-10   --> -123.4567890123p      --> -123p
    /// -1.234567890123E-11   --> -12.34567890123p      --> -12.3p
    /// -1.234567890123E-12   --> -1.234567890123p      --> -1.23p
    /// -1.234567890123E-13   --> -123.4567890123f      --> -123f
    /// -1.234567890123E-14   --> -12.34567890123f      --> -12.3f
    /// -1.234567890123E-15   --> -1.234567890123f      --> -1.23f
    /// -1.234567890123E-16   --> -123.4567890123a      --> -123a
    /// -1.234567890123E-17   --> -12.34567890123a      --> -12.3a
    /// -1.234567890123E-18   --> -1.234567890123a      --> -1.23a
    /// -1.234567890123E-19   --> -123.4567890123z      --> -123z
    /// -1.234567890123E-20   --> -12.34567890123z      --> -12.3z
    /// -1.234567890123E-21   --> -1.234567890123z      --> -1.23z
    /// -1.234567890123E-22   --> -123.4567890123y      --> -123y
    /// -1.234567890123E-23   --> -12.34567890123y      --> -12.3y
    /// -1.234567890123E-24   --> -1.234567890123y      --> -1.23y
    /// -1.234567890123E-25   --> -123.4567890123E-27   --> -123E-27
    /// -1.234567890123E-26   --> -12.34567890123E-27   --> -12.3E-27
    /// -1.234567890123E-27   --> -1.234567890123E-27   --> -1.23E-27
    /// -1.234567890123E-28   --> -123.4567890123E-30   --> -123E-30
    ///  1.234567890123E-28    ->  123.4567890123E-30    ->  123E-30
    ///  1.234567890123E-27    ->  1.234567890123E-27    ->  1.23E-27
    ///  1.234567890123E-26    ->  12.34567890123E-27    ->  12.3E-27
    ///  1.234567890123E-25    ->  123.4567890123E-27    ->  123E-27
    ///  1.234567890123E-24    ->  1.234567890123y       ->  1.23y
    ///  1.234567890123E-23    ->  12.34567890123y       ->  12.3y
    ///  1.234567890123E-22    ->  123.4567890123y       ->  123y
    ///  1.234567890123E-21    ->  1.234567890123z       ->  1.23z
    ///  1.234567890123E-20    ->  12.34567890123z       ->  12.3z
    ///  1.234567890123E-19    ->  123.4567890123z       ->  123z
    ///  1.234567890123E-18    ->  1.234567890123a       ->  1.23a
    ///  1.234567890123E-17    ->  12.34567890123a       ->  12.3a
    ///  1.234567890123E-16    ->  123.4567890123a       ->  123a
    ///  1.234567890123E-15    ->  1.234567890123f       ->  1.23f
    ///  1.234567890123E-14    ->  12.34567890123f       ->  12.3f
    ///  1.234567890123E-13    ->  123.4567890123f       ->  123f
    ///  1.234567890123E-12    ->  1.234567890123p       ->  1.23p
    ///  1.234567890123E-11    ->  12.34567890123p       ->  12.3p
    ///  1.234567890123E-10    ->  123.4567890123p       ->  123p
    ///  1.234567890123E-09    ->  1.234567890123n       ->  1.23n
    ///  1.234567890123E-08    ->  12.34567890123n       ->  12.3n
    ///  1.234567890123E-07    ->  123.4567890123n       ->  123n
    ///  1.234567890123E-06    ->  1.234567890123μ       ->  1.23μ
    ///  1.234567890123E-05    ->  12.34567890123μ       ->  12.3μ
    ///  0.0001234567890123    ->  123.4567890123μ       ->  123μ
    ///  0.001234567890123     ->  1.234567890123m       ->  1.23m
    ///  0.01234567890123      ->  12.34567890123m       ->  12.3m
    ///  0.1234567890123       ->  123.4567890123m       ->  123m
    ///  1.234567890123        ->  1.234567890123        ->  1.23
    ///  12.34567890123        ->  12.34567890123        ->  12.3
    ///  123.4567890123        ->  123.4567890123        ->  123
    ///  1234.567890123        ->  1.234567890123k       ->  1.23k
    ///  12345.67890123        ->  12.34567890123k       ->  12.3k
    ///  123456.7890123        ->  123.4567890123k       ->  123k
    ///  1234567.890123        ->  1.234567890123M       ->  1.23M
    ///  12345678.90123        ->  12.34567890123M       ->  12.3M
    ///  123456789.0123        ->  123.4567890123M       ->  123M
    ///  1234567890.123        ->  1.234567890123G       ->  1.23G
    ///  12345678901.23        ->  12.34567890123G       ->  12.3G
    ///  123456789012.3        ->  123.4567890123G       ->  123G
    ///  1234567890123         ->  1.234567890123T       ->  1.23T
    ///  12345678901230        ->  12.34567890123T       ->  12.3T
    ///  123456789012300       ->  123.4567890123T       ->  123T
    ///  1.234567890123E+15    ->  1.234567890123P       ->  1.23P
    ///  1.234567890123E+16    ->  12.34567890123P       ->  12.3P
    ///  1.234567890123E+17    ->  123.4567890123P       ->  123P
    ///  1.234567890123E+18    ->  1.234567890123E       ->  1.23E
    ///  1.234567890123E+19    ->  12.34567890123E       ->  12.3E
    ///  1.234567890123E+20    ->  123.4567890123E       ->  123E
    ///  1.234567890123E+21    ->  1.234567890123Z       ->  1.23Z
    ///  1.234567890123E+22    ->  12.34567890123Z       ->  12.3Z
    ///  1.234567890123E+23    ->  123.4567890123Z       ->  123Z
    ///  1.234567890123E+24    ->  1.234567890123Y       ->  1.23Y
    ///  1.234567890123E+25    ->  12.34567890123Y       ->  12.3Y
    ///  1.234567890123E+26    ->  123.4567890123Y       ->  123Y
    ///  1.234567890123E+27    ->  1.234567890123E+27    ->  1.23E+27
    ///  1.234567890123E+28    ->  12.34567890123E+27    ->  12.3E+27
    /// </example>
    /// <param name="d">the double to convert</param>
    /// <param name="significantFigures">The number of significant figures</param>
    /// <returns>A string</returns>
    
        6
  •  0
  •   PESMITH_MSFT    8 年前

    这是一条老掉牙的线索,但答案也许是正确的。现有代码的问题:它不处理NaN、任何无穷大、负数或非常小的数(比如double.epsilon)。你不能精确地通过。

    我的代码是:

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

    测试用例如下。我对测试用例的个人标准(很抱歉,这不遵循最新和最好的nunit指导):public static test()不接受参数并返回错误数。它通常调用一个私有静态testone(args,expected),它计算实际值(与预期值相比),并返回错误数。

       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;
        }
    
        7
  •  0
  •   Alex Kravchenko    7 年前

    这是另一种处理负数且不舍入的版本

    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}";
    }
    
        8
  •  -2
  •   Paul Sonier    16 年前

    要解决这个问题,您需要创建一个类(称为engineering),该类继承自重写toString()成员的float。

    编辑:好的,我现在明白了。不过,解决方案是子类化。