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 formattingdbl
to a fixed length =len
Double.parse
is converting the result again to double with the new length. Note: if th result containse
it will be removed after parseToString("#,#.#".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.