Basically I'm trying to perform number formatting in the exact same way as the Windows calculator does. Hence, my requirements are:
number.ToString("G16")
.number.ToString(String.Format("#,0.{0};-#,0.{0}", New String("#"c, 15)))
Any ideas on how to combine these together to get the same behavior as Windows calculator?
Some examples with the desired output:
I added an answer below which I would be using if the desired output can't be achieved using one string formatting. Feel free to suggest any optimizations/changes to that answer if you believe no direct way to achieve this (which is my original requirement)
Sorry if I caused some kind of confusion to anyone. 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.
Using the format() method "%. 2f" denotes 2 decimal places, "%. 3f" denotes 3 decimal places, and so on.
On the Home tab, in the Paragraph group, click Numbering. Note: To select a different number format, right-click a number in the list, point to Numbering, click Define New Number Format, and then select the options that you want.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With