Format decimal number with digit grouping and limit the number of digits

After a lot of search on this issue. You cannot perform this with a single format because you are asking about an IF .. ELSE LOGIC not for a one-way formatting (performing two formatting on a number)

IF d.ToString("G16") contains scientific notation

    ... do something

ELSE

    ... group digits

So you have to use an IF to achieve this

Str = If( num.ToString("G15").Contains("e"), num.ToString("G15"), num.ToString(String.Format("#,0.{0};-#,0.{0}", New String("#"c, 15))))

Update1

Based on your update use the following

Public Function FormatDouble(ByVal dbl As Double, ByVal len As Integer) As String

    Return Double.Parse(dbl.ToString("G" & len)).ToString("#,#.#".PadRight(len, "#"), System.Globalization.CultureInfo.InvariantCulture)

End Function
  • dbl.ToString("G" &len) is formatting dbl to a fixed length = len

  • Double.parse is converting the result again to double with the new length. Note: if th result contains e it will be removed after parse

  • ToString("#,#.#".PadRight(len, "#"), System.Globalization.CultureInfo.InvariantCulture) is adding Group digits to the resulted double

Note

When providing length ("G15") it will round the number to it. It may reduce length from decimal part but it doesn't from the integers it will round the number to the specified length. I.e. 1734.Tostring("G1") will returns 2000 but not 2 / 1734.Tostring("G2") will returns 1700 but not 17

If you want to reduce numbers you have to use String Functions like Substring And Left after the Tostring("G1")

Hope it helps


I don't know an easy way to do that in the way you are looking for.

But being a curious sort of fellow I did wonder how it could be achieved using only string methods.

To be clear, I'm not advocating this approach as a good solution - it's rather hard to understand in one line, but hey, an interesting exercise for me.

If you felt like doing it in one horrendous line (c#):

var num1 = 123123123.456456456;  // result: 123,123,123.4564565
//var num1 = 123123123456456456.78;  // result: 1.231231234564565E+17
//var num1 = 123123123456; // result: 1,231,231,234,564,564
//var num1 = 1231231; // result: 1,231,231

Console.WriteLine(long.Parse((num1.ToString("G16") + ".").Substring(0, (num1.ToString("G16") + ".").IndexOf('.'))).ToString("N0") + (num1.ToString("G16") + ".").Substring((num1.ToString("G16") + ".").IndexOf('.'), (num1.ToString("G16") + ".").LastIndexOf('.')- (num1.ToString("G16") + ".").IndexOf('.')));

Otherwise broken up a little; it's a little clearer what approach I'm taking:

var num1 = 123123123.456456456;
var num1a = num1.ToString("G16") + "."; 

Console.WriteLine(long.Parse(num1a.Substring(0, num1a.IndexOf('.'))).ToString("N0") + num1a.Substring(num1a.IndexOf('.'), num1a.LastIndexOf('.')- num1a.IndexOf('.')));

I'm adding a decimal point to the end of the string so that there is at least one decimal point in the number (string). Then grab the text to the left of the first decimal point and concatenate it with any text from the first and to the left of the last decimal point.

If there was no decimal point in the original string then these two points are the same - the substring 0 characters long - removing the added decimal point.


This is an answer I would be using if this can't be done using one string formatting:

Private Function RoundAndGroup(num As Decimal) As String
    ' This will round the input to limit the number of digit to 16.
    Dim rounded As String = num.ToString("G16")
    ' Take only the whole part of the number to group and then combine with the rounded part.
    Dim whole As String = rounded.Split(".")(0)
    ' Group the whole part (if any) and combine with the rounded part (also if any).
    Dim grouped As String = Long.Parse(whole).ToString("N0") & ' Thanks to KScandrett's comment
                            rounded.Substring(whole.Length)
    Return grouped
End Function

This will -AFAICT- produce my desired output (the same output of Windows calculator).

I just thought that there might be a simple one string formatting to achieve this and I was -and still am- curious to find out if that's true.