2016-12-06 111 views
8

基本上我試圖以與Windows計算器完全相同的方式執行數字格式設置。因此,我的要求是:使用數字分組格式化十進制數並限制數字位數

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

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


與期望輸出的一些例子:

Examples


我加入下面我將使用如果不能使用一個字符串來實現所希望的輸出的答案格式。如果您認爲沒有直接的方式來達到這個目標(這是我的原始要求),請隨時提出任何優化/更改該答案。

對不起,如果我對任何人造成某種混淆。我只是認爲可能會有一個簡單的字符串格式來實現這一點,而我是 - 並且很好奇,以確定這是否屬實。

+0

你應該給出例子。例如,你可以給第二個項目符號中的方法不輸出所需字符串的數字嗎?什麼是實際的字符串,你想要什麼? –

+0

@JeppeStigNielsen,更新了這個問題。 –

+0

[我已經告訴過你該怎麼做](http://stackoverflow.com/q/40953111/17034)。使用Math.Log10(Math.Abs​​(value))知道何時需要切換到「E」格式。 –

回答

6

在這個問題上有很多搜索後。因爲你是問關於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)))) 

UPDATE1

根據您的更新使用以下

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被再次轉換結果與新的長度增加一倍。 注意:如果第結果包含e它將被後取出解析

  • ToString("#,#.#".PadRight(len, "#"), System.Globalization.CultureInfo.InvariantCulture)是添加組數字以導致雙

當提供長度("G15")它將圓它的數量。它可能會減少小數部分的長度,但它不會從整數中減去指定長度的整數。即1734.Tostring("G1")將返回2000但不2/1734.Tostring("G2")將返回1700但不17

如果你想減少你必須使用字符串函數SubstringLeftTostring("G1")

後數希望它能幫助

+0

這甚至不會結合這兩種方法的優點。當我需要同時使用它們時,您總是最終只使用其中的一個(限制數字+組數字)。此外,「e」不是條件應該基於的唯一問題。感謝您的努力,雖然:) –

+3

你的例子不顯示你在說什麼。我沒有看到任何組合??!當發現科學記數法時,不允許分組 – Hadi

+1

「*關於如何將這些組合在一起以獲得與Windows計算器*相同的行爲的任何想法」。問題不在於結合科學記數法和數字分組。這是關於結合*數字分組*和*限制數字的數量*(只要科學記數法需要,''G16'就這樣做)。 –

0

您可以使用String.format來應用多種格式。閱讀關於Composite Formatting here

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

Tested in vb.net

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

可能需要在格式化時將數字轉換爲長整型,然後在您的最後進行測試。

對於第2部分,你可以使用N0添加逗號爲成千上萬的地方 - Standard Numeric Format Strings

+1

這不能工作。你不能格式化兩次。在第一次格式化後,在你的情況下,'.ToString(「G16」)',你有什麼是一個字符串。該字符串不會關心'N0'的事情。一個字符串不是可格式化的('string'不實現'IFormattable')。 –

+0

您是否看過我的評論? '您可能需要在格式化時將數字轉換爲長整型,然後在您的端點進行測試。「顯然,我沒有對它進行測試並提到過它。但無論如何,既然你測試過了,我會加上 – TheUknown

+0

@JeppeStigNielsen。衆所周知,感謝您的建議,但它不起作用。 –

3

這是我將使用的答案,如果這不能使用一個字符串格式完成:

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計算器相同的輸出)。

我只是認爲可能有一個簡單的一個字符串格式來實現這一點,我還是 - 很好奇,以確定是否屬實。

+1

你可以在分組中使用'Integer.Parse(whole).ToString(String.Format(「N0」))&...' –

+1

@KScandrett,+1好點。是的,因爲我只將這個格式應用到整個部分,所以不會有尾隨零。另外我應該使用'Long'而不是'Integer'。 –

4

我不知道一個簡單的方法來做到這一點,你正在尋找。

但作爲一個奇怪的人,我確實想知道如何才能使用字符串方法來實現。

要清楚的是,我並不是主張這種方法是一個很好的解決方案 - 它很難在一行中理解,但嘿,這對我來說是一個有趣的練習。

如果你覺得做一個可怕線(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個字符長 - 刪除添加的小數點。

+0

也許不只是字符串方法......我偷偷在裏面放了一個long.Parse()' –

+2

+1也是很好的答案。但是,我也可以將我的答案寫入一行代碼中,但那不是重點。我只是認爲可能有一個字符串格式化來實現這一點(類似於'num.ToString(「SOME_SORT_OF_FORMATTING」)'),但看起來這是不可能的,這就是爲什麼我接受哈迪的答案。 –