12

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.

Bill the Lizard
  • 369,957
  • 201
  • 546
  • 842
Simon
  • 8,517
  • 13
  • 64
  • 107

7 Answers7

4

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"
Jonathon Reinhart
  • 116,671
  • 27
  • 221
  • 298
2

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);
}
Eren Ersönmez
  • 36,276
  • 7
  • 63
  • 88
1

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.

V4Vendetta
  • 34,000
  • 7
  • 73
  • 81
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.

Michael Graczyk
  • 4,740
  • 2
  • 20
  • 32
0

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('.');
        }
Adil Mammadov
  • 7,996
  • 4
  • 26
  • 55
0

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
Parker
  • 1,027
  • 2
  • 13
  • 27
-2

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.

Esteban Araya
  • 27,658
  • 22
  • 99
  • 139
  • Yes, but considering the decimal place is in an unknown position, how many leading/trailing zeros are there? – Simon Aug 03 '12 at 04:35
  • @Simon, you can figure out the position of the decimal point by dividing by ten until you no longer get an integer. You could then build the format string as outlined above and putting the decimal place in the correct place. I don't know if you'll be able to do it with a predefined format string. I think you might have to build it every time. I'll keep thinking though. Good question! – Esteban Araya Aug 03 '12 at 04:37