簡體   English   中英

用數字分組格式化十進制數並限制位數

[英]Format decimal number with digit grouping and limit the number of digits

基本上,我試圖以與 Windows 計算器完全相同的方式執行數字格式化。 因此,我的要求是:

  • 將顯示位數限制為最大值(例如 16)。 我能夠使用number.ToString("G16")來完成。
  • 將數字分組添加到號碼。 我能夠使用: number.ToString(String.Format("#,0.{0};-#,0.{0}", New String("#"c, 15)))

關於如何將這些組合在一起以獲得與 Windows 計算器相同的行為的任何想法?


具有所需輸出的一些示例:

例子


我在下面添加了一個答案,如果使用一種字符串格式無法實現所需的輸出,我將使用該答案。 如果您認為沒有直接的方法可以實現這一點,請隨意建議對該答案進行任何優化/更改(這是我最初的要求)

對不起,如果我給任何人造成了某種混亂。 我只是認為可能有一個簡單的單字符串格式來實現這一點,我一直 - 而且仍然 - 很想知道這是否屬實。

在對這個問題進行了大量搜索之后。 您不能使用單一格式執行此操作,因為您詢問的是IF .. ELSE LOGIC 不是用於單向格式(對數字執行兩種格式

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

    ... do something

ELSE

    ... group digits

所以你必須使用IF來實現這一點

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

更新1

根據您的更新使用以下內容

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)dbl格式化為固定長度 = len

  • Double.parse正在將結果再次轉換為具有新長度的 double。 注意:如果結果包含e它將在解析后被刪除

  • ToString("#,#.#".PadRight(len, "#"), System.Globalization.CultureInfo.InvariantCulture)正在將組數字添加到結果雙ToString("#,#.#".PadRight(len, "#"), System.Globalization.CultureInfo.InvariantCulture)

筆記

當提供長度("G15")它會將數字四舍五入。 它可能會減少小數部分的長度,但不會減少整數,它將數字四舍五入到指定的長度。 1734.Tostring("G1")將返回2000但不是2 / 1734.Tostring("G2")將返回1700但不是17

如果你想減少數字,你必須在Tostring("G1")之后使用像SubstringLeft這樣的字符串函數

希望能幫助到你

我不知道以您正在尋找的方式做到這一點的簡單方法。

但是作為一個好奇的家伙,我確實想知道如何僅使用字符串方法來實現。

需要明確的是,我並不是在提倡將這種方法作為一個好的解決方案 - 用一句話很難理解,但是,嘿,對我來說是一個有趣的練習。

如果你想在一個可怕的行 (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('.')));

否則就分手一點; 我采取的方法更清楚一點:

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('.')));

我在字符串的末尾添加了一個小數點,以便數字(字符串)中至少有一個小數點。 然后抓取第一個小數點左側的文本,並將其與第一個和最后一個小數點左側的任何文本連接起來。

如果原始字符串中沒有小數點,那么這兩個點是相同的 - 子字符串長度為 0 個字符 - 刪除添加的小數點。

如果使用一種字符串格式無法做到這一點,這是我將使用的答案:

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

這將 -AFAICT- 產生我想要的輸出(與 Windows 計算器的輸出相同)。

我只是認為可能有一個簡單的單字符串格式來實現這一點,我一直 - 而且仍然 - 很想知道這是否屬實。

您可以使用String.format來應用多種格式。 在此處閱讀有關復合格式的信息

String.Format("{0:N0}", Clng(number.ToString("G16")))

在 vb.net 中測試

您可以刪除零或使用您的格式,但最初的問題是關於應用多種格式。

可能需要在格式化時將數字轉換為 long,最后進行測試。

對於第 2 部分,您可以使用N0為數千個位置添加逗號 - 標准數字格式字符串

static formatDecimal(decimal decimalVar, int size)
{
    return decimalVar.ToString("#.##").PadLeft(size, '0'); 
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM