String.Format - How can I format to x digits (regardless of decimal place)?

孤者浪人 提交于 2020-01-01 08:15:07

问题


I need to format a floating point number to x characters (6 in my case including the decimal point). My output also needs to include the sign of the number

So given the inputs, here are the expected outputs

1.23456   => +1.2345

-12.34567 => -12.345

-0.123456 => -0.1234

1234.567  => +1234.5

Please assume there is always a decimal place before the last character. I.e. there will be no 12345.6 number input - the input will always be less than or equal to 9999.9.

I'm thinking this has to be done conditionally.


回答1:


Here's a transparent way to do it without format strings (except for "F"):

  static void Main()
  {
     double y = 1.23456;
     Console.WriteLine(FormatNumDigits(y,5));
     y= -12.34567;
     Console.WriteLine(FormatNumDigits(y,5));
     y = -0.123456;
     Console.WriteLine(FormatNumDigits(y,5));
     y = 1234.567;
     Console.WriteLine(FormatNumDigits(y,5));

     y = 0.00000234;
     Console.WriteLine(FormatNumDigits(y,5));

     y = 1.1;
     Console.WriteLine(FormatNumDigits(y,5));
  }


  public string FormatNumDigits(double number, int x) {
     string asString = (number >= 0? "+":"") + number.ToString("F50",System.Globalization.CultureInfo.InvariantCulture);

     if (asString.Contains('.')) {
        if (asString.Length > x + 2) {
           return asString.Substring(0, x + 2);
        } else {
           // Pad with zeros
           return asString.Insert(asString.Length, new String('0', x + 2 - asString.Length));
        }
     } else {
        if (asString.Length > x + 1) {
           return asString.Substring(0, x + 1);
        } else {
           // Pad with zeros
           return asString.Insert(1, new String('0', x + 1 - asString.Length));
        }
     }
  }

Output:

  +1.2345
  -12.345
  -0.1234
  +1234.5
  +0.0000
  +1.1000

EDIT

Notice that it does not chop off trailing zeros.




回答2:


You mention "x characters". So we can simplify that to "x-1 digits", and just write code that shows x digits.

I think passing the "G" numeric format specifier to Double.ToString() is as close to built-in as you can get.

double d = 1234.56789;
string s = d.ToString("G6");           // "1234.57"

So we just expand that to manually add the "+" at the front:

if (d > 0)
    s = "+" + s;

Putting it all together in an extension method:

EDIT: Includes optional parameter to truncate

public static string ToStringWithSign(this double d, int digits, bool truncate = false)
{
    if (truncate) {
        double factor = Math.Pow(10, digits - 1);
        d = Math.Truncate(d * factor) / factor;
    }

    string s = d.ToString("G" + digits);
    if (d > 0)
        s = "+" + s;
    return s;
}

Results:

(1234.56789).ToStringWithSign(4);      // "+1235"
(1234.56789).ToStringWithSign(5);      // "+1234.6"
(1234.56789).ToStringWithSign(6);      // "+1234.57"
(-1234.56789).ToStringWithSign(6);     // "-1234.57"

(1.2345678).ToStringWithSign(6);       // "+1.23457"
(1.2345678).ToStringWithSign(6, true); // "+1.23456"



回答3:


If you want truncation:

string str = number.ToString("+0.00000;-0.00000").Substring(0,7);

If you want rounding:

string str = number.ToString("+0.0000;-0.0000");

EDIT: if you want, you can write a simple wrapper that takes the number of digits as a parameter:

string FormatDecimal(decimal value, int digits )
{
    return value
        .ToString(String.Format("+0.{0};-0.{0}", new string('0',digits - 2)))
        .Substring(0,digits+1);
}



回答4:


I believe if you want to output to 6 character inclusive of the decimal point, you can have a look at this

double val1 = -99.56789;
//string strval = val1.ToString("+#.######;-#.######");// add # for additional decimal places
string strval = val1.ToString("+#.000000;-#.000000");    
Console.WriteLine(strval.Substring(0,strval.Length >= 7 ? 7 : strval.Length));
 //output -99.567 if positive would output +99.567

You just need to transform the value to a string and then pick up the relevant 6 characters (the additional one is for the sign) from the outputted string.

There is no rounding in this case and fits your need, hope this is what you are looking out for.




回答5:


This should do what you want. It does round the last digit, though.

static string Format(double d)
{
    // define how many number should be visible
    int digits = 5;

    // Get the left part of the number (ignore negative sign for now)
    int s = Math.Abs(d).ToString("####0").Length;

    // Total size minus the amount of numbers left of the decimal point
    int precision = digits - s;

    // Left side for positive, right side for negative.
    // All it's doing is generating as many 0s as we need for precision.
    string format = String.Format("+###0.{0};-###0.{0}", new String('0', precision));
    return d.ToString(format);
}

Given your input this returns:

+1.2346
-12.346
-0.1235
+1234.6

It'll handle zeros no problem:

+0.1000
+0.0000
+1000.0



回答6:


Try this:

        double myDouble = 1546.25469874;
        string myStr = string.Empty;
        if (myDouble > 0)
        {
            myStr = myDouble.ToString("+0.0###");
        }
        else
        {
            myStr = myDouble.ToString("0.0####");
        }
        if (myStr.Length > 7)
        {
            myStr = myStr.Remove(7).TrimEnd('.');
        }



回答7:


As stated here by MSDN, "0" is the place holder for a digit. So, all you need is:

myDecimal.ToString("000000");

or

myDecimal.ToString("######");

if you don't want a digit present instead of a zero.



来源:https://stackoverflow.com/questions/11789194/string-format-how-can-i-format-to-x-digits-regardless-of-decimal-place

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!