views:

102

answers:

5

Hello, I have a problem and cant find a solution. I have numbers (decimal) like 85.12343 or 100 or 1.123324. I want to format this in a way that the result is always 13 chars long including the separator.

100          --> 100.000000000
1.123324 --> 1.12332400000

I tried with toString, but failed. How could I do this?

Thanks :)

+6  A: 
int digits = 13;
decimal d = 100433.2414242241214M;
int positive = Decimal.Truncate(d).ToString().Length;
int decimals = digits - positive - 1; //-1 for the dot
if (decimals < 0)
    decimals = 0;
string dec = d.ToString("f" + decimals);

It will not remove digits from the whole part, only the fraction, when needed.

Kobi
+1 for knowing the appropriate formatter, I can never remember any of the formatters other than "d".
Jimmy Hoffa
@Jimmy - I can never remember anything *besides* `#` and `0` `:)`
Kobi
Thats quite good, but does this work without rounding somehow?
grady
+3  A: 

I'd go with Kobi's answer, unless it's possible you could have more than 13 digits to start with, in which case you might need to do something like this (warning: I have not even attempted to make this efficient; surely there are ways it could be optimized if necessary):

public static string ToTrimmedString(this decimal value, int numDigits)
{
    // First figure out how many decimal places are to the left
    // of the decimal point.
    int digitsToLeft = 0;

    // This should be safe since you said all inputs will be <= 100M anyway.
    int temp = decimal.ToInt32(Math.Truncate(value));
    while (temp > 0)
    {
        ++digitsToLeft;
        temp /= 10;
    }

    // Then simply display however many decimal places remain "available,"
    // taking the value to the left of the decimal point and the decimal point
    // itself into account. (If negative numbers are a possibility, you'd want
    // to subtract another digit for negative values to allow for the '-' sign.)
    return value.ToString("#." + new string('0', numDigits - digitsToLeft - 1));
}

Example inputs/output:

Input                     Output
---------------------------------------
100                       100.000000000
1.232487                  1.23248700000
1.3290435309439872321     1.32904353094
100.320148109932888473    100.320148110
0.000383849080819849081   .000383849081
0.0                       .000000000000
Dan Tao
+1  A: 

Besides simply padding the string you can do some more elaborate math to determine the number of digits:

String FormatField(Int32 fieldWidth, Decimal value) {
  var integerPartDigits =
    value != Decimal.Zero ? (int) Math.Log10((Double) value) + 1 : 1;
  var fractionalPartDigits = Math.Max(0, fieldWidth - integerPartDigits - 1);
  return value.ToString("F" + fractionalPartDigits);
}

Note that if the value is negative or has an integer part with one less digit than the field width you will not get the desired result. However, you can modify the code to accommodate these cases based on exactly how you want to format and align these numbers.

Martin Liversage
+1 - I've posted almost the same. Didn't use `log` though, it seemed strange for a `decimal`.
Kobi
+1  A: 

Quick 'n' dirty:

return (value.ToString("0.#") + "0000000000000").Substring(0, 13);
teedyay
Nice, but it doesn't round the number.
Kobi
+1  A: 
string formatted = original.ToString("0.000000000000").Remove(13);
LukeH