2014-10-05 3 views
0

Интересно, какой был бы лучший способ форматирования чисел, чтобы NumberGroupSeparator работал не только на целой части слева от запятой, но и на дробной части справа запятой.Децимальный разделитель группы для дробной части

Math.PI.ToString("###,###,##0.0##,###,###,###") // As documented .. 
               // ..this doesn't work 
3.14159265358979        // result 
3.141,592,653,589,79       // desired result 

Как указано на MSDN в NumberGroupSeparator работает только слева от запятой. Интересно, почему??

+0

потому что он является недействительным. они не будут группироваться одинаково (тысячи, десятки тысяч, сотни тысяч), если первая группа не будет 2 пункта: '3.14,159,265,358,979' – Plutonix

+0

А? Очевидно, что нужно группировать, начиная с запятой и десятых, сотый и тысячный будут делать совершенно нормальную группу! Это не то, о чем речь - речь идет о читаемости! – TaW

+2

@TaW Немного субъективно, но это не читаемо для меня. Числовые запятые группы указывают, что это большое количество (сотни миллиардов или что-то еще), пока вы не заметите точку, которая выглядит действительно странно. Это не формат, который обычно используется, и это, вероятно, причина, по которой он не работает. Перед вашим вопросом я бы не догадался, что кто-то захочет форматировать их номера. – BartoszKP

ответ

0

КИ, не моя сильная сторона, но я предполагаю, что это может быть моей лучшей ставкой:

string input = Math.PI.ToString(); 
string decSeparator = System.Threading.Thread.CurrentThread 
         .CurrentCulture.NumberFormat.NumberGroupSeparator; 
Regex RX = new Regex(@"([0-9]{3})"); 
string result = RX.Replace(input , @"$1" + decSeparator); 

Спасибо за прослушивание ..

0

Немного неуклюжий, и она не будет работать для научных чисел, но вот попробовать:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var π=Math.PI*10000; 

     Debug.WriteLine(Display(π)); 
     // 31,415.926,535,897,931,899 
    } 

    static string Display(double x) 
    { 
     int s=Math.Sign(x); 
     x=Math.Abs(x); 
     StringBuilder text=new StringBuilder(); 
     var y=Math.Truncate(x); 
     text.Append((s*y).ToString("#,#")); 
     x-=y; 
     if (x>0) 
     { 
      // 15 decimal places is max reasonable precision 
      y=Math.Truncate(x*Math.Pow(10, 15)); 
      text.Append("."); 
      text.Append(y.ToString("#,#").TrimEnd('0')); 
     } 
     return text.ToString(); 
    } 

} 
0

Это может быть лучше работать со строкой, сгенерированного вашим .ToString():

class Program 
{ 
    static string InsertSeparators(string s) 
    { 
     string decSeparator = System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator; 

     int separatorPos = s.IndexOf(decSeparator); 
     if (separatorPos >= 0) 
     { 
      string decPart = s.Substring(separatorPos + decSeparator.Length); 
      // split the string into parts of 3 or less characters 
      List<String> parts = new List<String>(); 
      for (int i = 0; i < decPart.Length; i += 3) 
      { 
       string part = ""; 
       for (int j = 0; (j < 3) && (i + j < decPart.Length); j++) 
       { 
        part += decPart[i + j]; 
       } 
       parts.Add(part); 
      } 
      string groupSeparator = System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberGroupSeparator; 
      s = s.Substring(0, separatorPos) + decSeparator + String.Join(groupSeparator, parts); 
     } 

     return s; 

    } 

    static void Main(string[] args) 
    { 

     for (int n = 0; n < 15; n++) 
     { 
      string s = Math.PI.ToString("0." + new string('#', n)); 
      Console.WriteLine(InsertSeparators(s)); 
     } 

     Console.ReadLine(); 

    } 
} 

выходов:

3 
3.1 
3.14 
3.142 
3.141,6 
3.141,59 
3.141,593 
3.141,592,7 
3.141,592,65 
3.141,592,654 
3.141,592,653,6 
3.141,592,653,59 
3.141,592,653,59 
3.141,592,653,589,8 
3.141,592,653,589,79