views:

80

answers:

1

I've got the following method:

public static string ReturnFormat(string input, int maxLength, int decimalPrecision, char formatChar)
  {
   string[] format = new string[2];
   string[] inputs = new string[2];

   inputs = input.Split(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0]);

   if (input.Length > maxLength)
   {
    int offset = 0;
    int counter = 0;

    if (inputs[0].Length > maxLength - (1 + decimalPrecision))
    {
     offset = maxLength - (1 + decimalPrecision);
    }
    else
     offset = inputs[0].Length;

    for (int i = 0; i < offset; i++)
    {
     format[0] += formatChar;

     if (counter < decimalPrecision)
     {
      format[1] += '0';
      counter++;
     }
    }

    System.Windows.Forms.MessageBox.Show("{0:" + format[0] + "." + format[1] + "}");
    return String.Format(CultureInfo.CurrentCulture, "{0:" + format[0] + "." + format[1] + "}", input);
   }
   else
    return input;
  }

Which say I'm using as:

ReturnFormat("12.3456789011243", 10, 2, '#') // format is {0:##.00} // output 12.3456789011243
ReturnFormat("12345678901.1243", 10, 2, '#') // format is {0:#######.00} // output 12345678901.1243

Now my issue is that the input string is not formatted well, still the format strig appears to be ok. Any ideas of what I'm doing wrong?

+2  A: 

Your input is a String not a Double, so it gets formatted like a string: the formatting does not know about decimal places in that case.

You could use Double.Parse() to transform the string into a Double value, but take care of using the right culture.

Another thing, is there a specific reason for not using the more natural format {0:0.00} in both cases? If you really mean to use a placeholder for digits then # is ok, otherwise 0 is best.

Tested solution (beware it truncates and does not round) I needed some time to understand what was actually wanted:

public static string ReturnFormat(string input, int maxLength, int decimalPrecision)
{
    if (input.Length <= maxLength)
        return input;
    Char separator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0];
    string[] inputs = input.Split(separator);
    // NB: truncating rather than rounding
    if (inputs[1].Length > decimalPrecision)
        inputs[1] = inputs[1].Substring(0, decimalPrecision);
    int digits = (maxLength - decimalPrecision - 1);
    // NB: truncating rather than rounding, adding ~ to signalize the
    // presence of missing significant digits
    if (inputs[0].Length > digits)
        inputs[0] = inputs[0].Substring(0, digits-1) + "~";
    return inputs[0] + separator + inputs[1];
}
jdehaan
OK,So I've used Double.Parse() and it works ok in 1st case (12.3456789011243 returns 12.35) but doesn't work proper on 2nd (12345678901.1243 returns the same)Still, the format is ok i guess ( {0:#######.00} ) in the 2nd case.
wikiz
jdehaan
Do not hesitate to contact me for other questions or comments regarding formatting, I try to keep that sheet up-to-date. I think you will be happier with 0.00 as a format string instead of doing that complicated format string computation.
jdehaan
The thing is that i need to display a value at a fixed length and that's why I'm trying to use this. Since it's a must in my case to display a value at fixed length I can't use 0.00 :(
wikiz
Are you aware that you essentially are changing the value but still keeps the decimals? It looks fishy.
Jonas Elfström
Yes, I'm aware of that.
wikiz
Fishy or not, I would rather use a `Regex.Replace` in your case with a `(\d{n})\d*\.(\d+)` and replace with \1~.\2 for example using ~ to signalize that significant digits are missing to remove a bit of the fishy taste :-)
jdehaan
I made an edit to provide some working code with another way to solve your problem I hope. I neeeded some time to understand your goal. Hope it helps.
jdehaan