[英]Format decimal number with digit grouping and limit the number of digits
Basically I'm trying to perform number formatting in the exact same way as the Windows calculator does.基本上,我试图以与 Windows 计算器完全相同的方式执行数字格式化。 Hence, my requirements are:
因此,我的要求是:
number.ToString("G16")
.number.ToString("G16")
来完成。number.ToString(String.Format("#,0.{0};-#,0.{0}", New String("#"c, 15)))
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?关于如何将这些组合在一起以获得与 Windows 计算器相同的行为的任何想法?
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.
我只是认为可能有一个简单的单字符串格式来实现这一点,我一直 - 而且仍然 - 很想知道这是否属实。
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 .. ELSE
LOGIC 不是用于单向格式(对数字执行两种格式)
IF d.ToString("G16") contains scientific notation
... do something
ELSE
... group digits
So you have to use an IF
to achieve this所以你必须使用
IF
来实现这一点
Str = If( num.ToString("G15").Contains("e"), num.ToString("G15"), num.ToString(String.Format("#,0.{0};-#,0.{0}", New String("#"c, 15))))
Update1更新1
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
dbl.ToString("G" &len)
将dbl
格式化为固定长度 = len
Double.parse
is converting the result again to double with the new length. Double.parse
正在将结果再次转换为具有新长度的 double。 Note: if th result contains e
it will be removed after parse注意:如果结果包含
e
它将在解析后被删除
ToString("#,#.#".PadRight(len, "#"), System.Globalization.CultureInfo.InvariantCulture)
is adding Group digits to the resulted double ToString("#,#.#".PadRight(len, "#"), System.Globalization.CultureInfo.InvariantCulture)
正在将组数字添加到结果双ToString("#,#.#".PadRight(len, "#"), System.Globalization.CultureInfo.InvariantCulture)
Note笔记
When providing length ("G15")
it will round the number to it.当提供长度
("G15")
它会将数字四舍五入。 It may reduce length from decimal part but it doesn't from the integers it will round the number to the specified length.它可能会减少小数部分的长度,但不会减少整数,它将数字四舍五入到指定的长度。 Ie
1734.Tostring("G1")
will returns 2000
but not 2
/ 1734.Tostring("G2")
will returns 1700
but not 17
即
1734.Tostring("G1")
将返回2000
但不是2
/ 1734.Tostring("G2")
将返回1700
但不是17
If you want to reduce numbers you have to use String Functions like Substring
And Left
after the Tostring("G1")
如果你想减少数字,你必须在
Tostring("G1")
之后使用像Substring
和Left
这样的字符串函数
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#):如果你想在一个可怕的行 (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.如果原始字符串中没有小数点,那么这两个点是相同的 - 子字符串长度为 0 个字符 - 删除添加的小数点。
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).这将 -AFAICT- 产生我想要的输出(与 Windows 计算器的输出相同)。
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.我只是认为可能有一个简单的单字符串格式来实现这一点,我一直 - 而且仍然 - 很想知道这是否属实。
You can use String.format to apply multiple formats.您可以使用String.format来应用多种格式。 Read about Composite Formatting here :
在此处阅读有关复合格式的信息:
String.Format("{0:N0}", Clng(number.ToString("G16")))
You can drop the zeros or use your formatting, but the original question was about applying multiple formats.您可以删除零或使用您的格式,但最初的问题是关于应用多种格式。
You might need to convert the number to long while formatting, test it out at your end.您
可能需要在格式化时将数字转换为 long,最后进行测试。
For part 2, you can just use N0
to add the commas for thousands places - Standard Numeric Format Strings对于第 2 部分,您可以使用
N0
为数千个位置添加逗号 - 标准数字格式字符串
static formatDecimal(decimal decimalVar, int size)
{
return decimalVar.ToString("#.##").PadLeft(size, '0');
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.