字符串格式数字为数百万,数字为四舍五入

时间:2015-05-12 02:22:24

标签: c# .net currency

我正在尝试格式化显示价格,我想显示一个带有百万(M)或千(K)后缀的数字,但只能显示最多3个值,向下舍入。

我发现this question与我想要的非常接近,但是没有处理舍入(特别是,总是四舍五入)

同样地,with this question你无法控制四舍五入。

示例输入/预期输出:

1 = 1
10 = 10
100 = 100
1000 = 1K
100000 = 100K
125000 = 125K
125900 = 125K
1000000 = 1M
1250000 = 1.25M
1258000 = 1.25M
10000000 = 10M
10500000 = 10.5M
100000000 = 100M
100100000 = 100M

我基本上只想显示3个值。

我无法看到我如何使用"," custom specifier并指定舍入。

我最初的想法表明我需要使用上面的Math.Floor和一些.ToString()格式化魔法的组合,但我不确定从哪里开始。

有人能帮助我吗?

提前致谢。

6 个答案:

答案 0 :(得分:8)

这应该有所帮助,并结合您链接到的其他问题中的一种格式化技巧。

  internal long MaxThreeSignificantDigits(long x)
  {
     int i = (int)Math.Log10(x);
     i = Math.Max(0, i - 2);
     i = (int)Math.Pow(10, i);
     return x / i * i;
  }

编辑:

好的,这个怎么样?

 Console.WriteLine(SO30180672.FormatNumber(1));
 Console.WriteLine(SO30180672.FormatNumber(12));
 Console.WriteLine(SO30180672.FormatNumber(123));
 Console.WriteLine(SO30180672.FormatNumber(1234));
 Console.WriteLine(SO30180672.FormatNumber(12345));
 Console.WriteLine(SO30180672.FormatNumber(123456));
 Console.WriteLine(SO30180672.FormatNumber(1234567));
 Console.WriteLine(SO30180672.FormatNumber(12345678));
 Console.WriteLine(SO30180672.FormatNumber(123456789));

以下部分从此处复制:https://stackoverflow.com/a/23384710/253938

   internal class SO30180672
   {
      internal static string FormatNumber(long num)
      {
         num = MaxThreeSignificantDigits(num);

         if (num >= 100000000)
            return (num / 1000000D).ToString("0.#M");
         if (num >= 1000000)
            return (num / 1000000D).ToString("0.##M");
         if (num >= 100000)
            return (num / 1000D).ToString("0k");
         if (num >= 100000)
            return (num / 1000D).ToString("0.#k");
         if (num >= 1000)
            return (num / 1000D).ToString("0.##k");
         return num.ToString("#,0");
      }


      internal static long MaxThreeSignificantDigits(long x)
      {
         int i = (int)Math.Log10(x);
         i = Math.Max(0, i - 2);
         i = (int)Math.Pow(10, i);
         return x / i * i;
      }
   }

编辑2 - 非常感谢@Rhexis

   internal class SO30180672
   {
      internal static void RunTest()
      {
         Console.WriteLine(FormatNumber(1));
         Console.WriteLine(FormatNumber(10));
         Console.WriteLine(FormatNumber(100));
         Console.WriteLine(FormatNumber(1000));
         Console.WriteLine(FormatNumber(10000));
         Console.WriteLine(FormatNumber(100000));
         Console.WriteLine(FormatNumber(125000));
         Console.WriteLine(FormatNumber(125900));
         Console.WriteLine(FormatNumber(1000000));
         Console.WriteLine(FormatNumber(1250000));
         Console.WriteLine(FormatNumber(1258000));
         Console.WriteLine(FormatNumber(10000000));
         Console.WriteLine(FormatNumber(10500000));
         Console.WriteLine(FormatNumber(100000000));
         Console.WriteLine(FormatNumber(100100000));
      }

      private static string FormatNumber(long num)
      {
         // Ensure number has max 3 significant digits (no rounding up can happen)
         long i = (long)Math.Pow(10, (int)Math.Max(0, Math.Log10(num) - 2));
         num = num / i * i;

         if (num >= 1000000000)
            return (num / 1000000000D).ToString("0.##") + "B";
         if (num >= 1000000)
            return (num / 1000000D).ToString("0.##") + "M";
         if (num >= 1000)
            return (num / 1000D).ToString("0.##") + "K";

         return num.ToString("#,0");
      }
   }

答案 1 :(得分:5)

这是我的测试输出代码

1249            1.24K
12499           12.4K
124999          124K
1249999         1.24M
12499999        12.4M
124999999       124M
1249999999      1.24B

代码最多输出三位数。

    static string FormatNumber(uint n)
    {
        if (n < 1000)
            return n.ToString();

        if (n < 10000)
            return String.Format("{0:#,.##}K", n - 5);

        if (n < 100000)
            return String.Format("{0:#,.#}K", n - 50);

        if (n < 1000000)
            return String.Format("{0:#,.}K", n - 500);

        if (n < 10000000)
            return String.Format("{0:#,,.##}M", n - 5000);

        if (n < 100000000)
            return String.Format("{0:#,,.#}M", n - 50000);

        if (n < 1000000000)
            return String.Format("{0:#,,.}M", n - 500000);

        return String.Format("{0:#,,,.##}B", n - 5000000);
    }

答案 2 :(得分:2)

由于格式基本上会根据范围发生变化,因此您可能需要一些类似于下面的条件格式。我只测试了提供的样本集,因此请确保这适用于所有预期值。

.state('cloud', {
    url: '/cloud',
    views: { 
        'main': { templateUrl: 'main.html', controller: 'cloud' },
        'second': { templateUrl: 'second.html', controller: 'cloud' }
    }
})

答案 3 :(得分:1)

感谢大家的帮助,让我走上正确的道路,自己搞清楚。

<select>
  <option selected="selected" disabled="disabled">dropdown</option>
  @foreach (System.Data.DataRow row in ViewBag.Template.Rows)
  {
    <option value="@row[1].ToString()">@row[0].ToString()</option>
  }
</select>
<textarea></textarea>

答案 4 :(得分:0)

我知道这是一个老问题,但是我不禁注意到这些答案中的大多数都不是很可扩展的,其中大多数都是非常相似的代码行,重复了更多的值。我需要一些可以处理更大值的东西,因此我尝试以一种聪明的方式尝试使用数学,而不是重复的代码。这确实需要使用浮点数学运算(双精度),因为无符号长整数的最大值仅为1.84e + 19。我的解决方案:

public static string GetStringRepresentation(double count)
{
    string tokens = " KMBtqQsSondUDT"; //Infinitely expandable (at least to the limit of double floating point values)
    for (double i = 1; true; i += 1)
    {
        double val = Math.Pow(1000, i);
        if (val > count)
        {
            return $"{count / Math.Pow(1000, i - 1)}{tokens[(int)i - 1]}".Trim();
        }
    }
}

测试代码:

Console.WriteLine("                     1: " + GetStringRepresentation(                  1).PadLeft(7, ' '));
Console.WriteLine("                    12: " + GetStringRepresentation(                 12).PadLeft(7, ' '));
Console.WriteLine("                   123: " + GetStringRepresentation(                123).PadLeft(7, ' '));
Console.WriteLine("                  1230: " + GetStringRepresentation(               1230).PadLeft(7, ' '));
Console.WriteLine("                 12340: " + GetStringRepresentation(              12340).PadLeft(7, ' '));
Console.WriteLine("                123450: " + GetStringRepresentation(             123450).PadLeft(7, ' '));
Console.WriteLine("               1230000: " + GetStringRepresentation(            1230000).PadLeft(7, ' '));
Console.WriteLine("              12340000: " + GetStringRepresentation(           12340000).PadLeft(7, ' '));
Console.WriteLine("             123450000: " + GetStringRepresentation(          123450000).PadLeft(7, ' '));
Console.WriteLine("            1230000000: " + GetStringRepresentation(         1230000000).PadLeft(7, ' '));
Console.WriteLine("         1230000000000: " + GetStringRepresentation(      1230000000000).PadLeft(7, ' '));
Console.WriteLine("      1230000000000000: " + GetStringRepresentation(   1230000000000000).PadLeft(7, ' '));
Console.WriteLine("   1230000000000000000: " + GetStringRepresentation(1230000000000000000).PadLeft(7, ' '));

输出:

                     1:       1
                    12:      12
                   123:     123
                  1230:   1,23K
                 12340:  12,34K
                123450: 123,45K
               1230000:   1,23M
              12340000:  12,34M
             123450000: 123,45M
            1230000000:   1,23B
         1230000000000:   1,23t
      1230000000000000:   1,23q
   1230000000000000000:   1,23Q

答案 5 :(得分:0)

下面是一个VBS / VbScript函数。 NB => VB和VBA提供直接格式调用。

'用法:使用大于千的符号返回数字(例如:234,789,145 = 234.8M)

函数Format_Large_Number(nb,nbDigit)

' Safety
If Not IsNumeric(nb) Then FormatLargeNumber = nb : Exit Function
If nbDigit < 1 Then nbDigit = 1
If nbDigit > 3 Then nbDigit = 3

' Initiate var
Dim rtnNb    : rtnNb    = nb
Dim nbFormat : nbFormat = FormatCurrency(rtnNb, 0, vbTrue, vbTrue)
               nbFormat = Trim(Replace(nbFormat, "$", ""))
Dim nbSymbol : nbSymbol = ""
Dim nbDecRnd : nbDecRnd = ""
Dim arrNb    : arrNb    = Split(nbFormat, " ")

' Asign symbol
Select Case UBound(arrNb)
    Case 0
        nbSymbol = ""   ' Hundred
    Case 1
        nbSymbol = "K"  ' Thousand
    Case 2
        nbSymbol = "M"  ' Million
    Case 3
        nbSymbol = "G"  ' Billion
    Case 4
        nbSymbol = "T"  ' Trillion
    Case 5
        nbSymbol = "P"  ' Quadrillion
    Case 6
        nbSymbol = "E"  ' Quintillion
End Select

' Concatenate rtn string
If Ubound(arrNb) > 0 Then
    If nbDigit < 3 Then
        If CInt(arrNb(1)) > 499 Then
            nbDecRnd = CStr(CInt(Left(arrNb(1),nbDigit)) + 1) ' Ceil decimal rtn
        Else
            nbDecRnd = Left(arrNb(1),nbDigit)
        End If
    Else
        nbDecRnd = Left(arrNb(1),nbDigit)
    End If
    
    rtnNb = arrNb(0) & "," & nbDecRnd & nbSymbol    ' All others
Else
    
    rtnNb = arrNb(0) & nbSymbol                     ' Hundred
End If

' Rtn value
Format_Large_Number = rtnNb

结束功能