2010-01-25 32 views

Trả lời

28

Như thế này: (EDIT: Tested)

static string FormatNumber(int num) { 
    if (num >= 100000) 
     return FormatNumber(num/1000) + "K"; 
    if (num >= 10000) { 
     return (num/1000D).ToString("0.#") + "K"; 
    } 
    return num.ToString("#,0"); 
} 

Ví dụ:

  • 1 =>1
  • 23 =>23
  • 136 =>136
  • 6968 =>6,968
  • 23067 =>23.1K
  • 133031 =>133K

Lưu ý rằng điều này sẽ cung cấp cho các giá trị xa lạ đối với số> = 10 .
Ví dụ: 12345678 trở thành 12.3KK.

+0

> = là ý của bạn là gì? – CodeMonkey

+0

@CodeMonkey: Có; cảm ơn. – SLaks

+0

Trả lại cho số 12392 của Earwicker là bao nhiêu? – DOK

0

Something như thế này:

string formatted; 
if (num >= 1000) { 
    formatted = ((double)num/1000.0).ToString("N1") + "k"; 
} else { 
    formatted = num.ToString("N0"); 
} 
+1

Điều đó sẽ in 36k cho đại diện của bạn, không 36.8k. Phiên bản StackOverflow giữ một số con số đáng kể. –

0

Nếu số lớn hơn một số ngưỡng, chia nó bằng 1000 và sau đó định dạng nó để tuy nhiên nhiều chữ số thập phân bạn cần .

int input = 12392; // for example 

if (input >= 10000) 
{ 
    double thousands = input/1000.0; 
    Console.WriteLine(string.Format("{0}K", thousands)); 
} 
+0

Trả lại cho hiển thị là gì? – DOK

17

Bạn có thể thùng một CustomFormater như thế này:

public class KiloFormatter: ICustomFormatter, IFormatProvider 
{ 
    public object GetFormat(Type formatType) 
    { 
     return (formatType == typeof(ICustomFormatter)) ? this : null; 
    } 

    public string Format(string format, object arg, IFormatProvider formatProvider) 
    { 
     if (format == null || !format.Trim().StartsWith("K")) { 
      if (arg is IFormattable) { 
       return ((IFormattable)arg).ToString(format, formatProvider); 
      } 
      return arg.ToString(); 
     } 

     decimal value = Convert.ToDecimal(arg); 

     // Here's is where you format your number 

     if (value > 1000) { 
      return (value/1000).ToString() + "k"; 
     } 

     return value.ToString(); 
    } 
} 

Và sử dụng nó như thế này:

String.Format(new KiloFormatter(), "{0:K}", 15600); 

chỉnh sửa: đổi tên CurrencyFormatter để KiloFormatter

+4

Con người, đó là rất nhiều mã chỉ để định dạng một số. – DOK

+1

Phải đồng ý với DOK. Điều đó dường như khá dư thừa;) – CodeMonkey

+8

@DOK: Đây là cách tiêu chuẩn để tạo các Form định dạng có thể tái sử dụng trong .NET Framework –

18

Đoạn code dưới đây được thử nghiệm lên to int.MaxValue Đây không phải là mã đẹp nhất nhưng hiệu quả nhất. Nhưng bạn có thể sử dụng nó như:

123.KiloFormat(); 4332.KiloFormat(); 2332124.KiloFormat(); int.MaxValue.KiloFormat(); (int1 - int2 * int3) .KiloFormat();

v.v ...

public static class Extensions 
{ 
    public static string KiloFormat(this int num) 
    { 
     if (num >= 100000000) 
      return (num/1000000).ToString("#,0M"); 

     if (num >= 10000000) 
      return (num/1000000).ToString("0.#") + "M"; 

     if (num >= 100000) 
      return (num/1000).ToString("#,0K"); 

     if (num >= 10000) 
      return (num/1000).ToString("0.#") + "K"; 

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

tôi chỉ viết một số để cung cấp thông tin đầy đủ

public static class SIPrefix 
{ 
    private static List<SIPrefixInfo> _SIPrefixInfoList = new 
     List<SIPrefixInfo>(); 

    static SIPrefix() 
    { 
     _SIPrefixInfoList = new List<SIPrefixInfo>(); 
     LoadSIPrefix(); 
    } 

    public static List<SIPrefixInfo> SIPrefixInfoList 
    { 
     get 
     { 
      SIPrefixInfo[] siPrefixInfoList = new SIPrefixInfo[6]; 
      _SIPrefixInfoList.CopyTo(siPrefixInfoList); 
      return siPrefixInfoList.ToList(); 
     } 
    } 

    private static void LoadSIPrefix() 
    { 
     _SIPrefixInfoList.AddRange(new SIPrefixInfo[]{ 
      new SIPrefixInfo() {Symbol = "Y", Prefix = "yotta", Example = 1000000000000000000000000.00M, ZeroLength = 24, ShortScaleName = "Septillion", LongScaleName = "Quadrillion"}, 
      new SIPrefixInfo() {Symbol = "Z", Prefix = "zetta", Example = 1000000000000000000000M, ZeroLength = 21, ShortScaleName = "Sextillion", LongScaleName = "Trilliard"}, 
      new SIPrefixInfo() {Symbol = "E", Prefix = "exa", Example = 1000000000000000000M, ZeroLength = 18, ShortScaleName = "Quintillion", LongScaleName = "Trillion"}, 
      new SIPrefixInfo() {Symbol = "P", Prefix = "peta", Example = 1000000000000000M, ZeroLength = 15, ShortScaleName = "Quadrillion", LongScaleName = "Billiard"}, 
      new SIPrefixInfo() {Symbol = "T", Prefix = "tera", Example = 1000000000000M, ZeroLength = 12, ShortScaleName = "Trillion", LongScaleName = "Billion"}, 
      new SIPrefixInfo() {Symbol = "G", Prefix = "giga", Example = 1000000000M, ZeroLength = 9, ShortScaleName = "Billion", LongScaleName = "Milliard"}, 
      new SIPrefixInfo() {Symbol = "M", Prefix = "mega", Example = 1000000M, ZeroLength = 6, ShortScaleName = "Million", LongScaleName = "Million"}, 
      new SIPrefixInfo() {Symbol = "K", Prefix = "kilo", Example = 1000M, ZeroLength = 3, ShortScaleName = "Thousand", LongScaleName = "Thousand"}, 
      new SIPrefixInfo() {Symbol = "h", Prefix = "hecto", Example = 100M, ZeroLength = 2, ShortScaleName = "Hundred", LongScaleName = "Hundred"}, 
      new SIPrefixInfo() {Symbol = "da", Prefix = "deca", Example = 10M, ZeroLength = 1, ShortScaleName = "Ten", LongScaleName = "Ten"}, 
      new SIPrefixInfo() {Symbol = "", Prefix = "", Example = 1M, ZeroLength = 0, ShortScaleName = "One", LongScaleName = "One"}, 
     }); 
    } 

    public static SIPrefixInfo GetInfo(long amount, int decimals) 
    { 
     return GetInfo(Convert.ToDecimal(amount), decimals); 
    } 

    public static SIPrefixInfo GetInfo(decimal amount, int decimals) 
    { 
     SIPrefixInfo siPrefixInfo = null; 
     decimal amountToTest = Math.Abs(amount); 

     var amountLength = amountToTest.ToString("0").Length; 
     if(amountLength < 3) 
     { 
      siPrefixInfo = _SIPrefixInfoList.Find(i => i.ZeroLength == amountLength).Clone() as SIPrefixInfo; 
      siPrefixInfo.AmountWithPrefix = Math.Round(amount, decimals).ToString(); 

      return siPrefixInfo; 
     } 

     siPrefixInfo = _SIPrefixInfoList.Find(i => amountToTest > i.Example).Clone() as SIPrefixInfo; 

     siPrefixInfo.AmountWithPrefix = Math.Round(
      amountToTest/Convert.ToDecimal(siPrefixInfo.Example), decimals).ToString() 
             + siPrefixInfo.Symbol; 

     return siPrefixInfo; 
    } 
} 

public class SIPrefixInfo : ICloneable 
{ 
    public string Symbol { get; set; } 
    public decimal Example { get; set; } 
    public string Prefix { get; set; } 
    public int ZeroLength { get; set; } 
    public string ShortScaleName { get; set; } 
    public string LongScaleName { get; set; } 
    public string AmountWithPrefix { get; set; } 

    public object Clone() 
    { 
     return new SIPrefixInfo() 
          { 
           Example = this.Example, 
           LongScaleName = this.LongScaleName, 
           ShortScaleName = this.ShortScaleName, 
           Symbol = this.Symbol, 
           Prefix = this.Prefix, 
           ZeroLength = this.ZeroLength 
          }; 

    } 
} 

Sử dụng:

var amountInfo = SIPrefix.GetInfo(10250, 2); 
var amountInfo2 = SIPrefix.GetInfo(2500000, 0); 

amountInfo.AmountWithPrefix // 10.25K 
amountInfo2.AmountWithPrefix // 2M 
2

tôi đã viết phương pháp này để rút gọn long số:

public string minifyLong(long value) 
    { 
     if (value >= 100000000000) 
      return (value/1000000000).ToString("#,0") + " B"; 
     if (value >= 10000000000) 
      return (value/1000000000D).ToString("0.#") + " B"; 
     if (value >= 100000000) 
      return (value/1000000).ToString("#,0") + " M"; 
     if (value >= 10000000) 
      return (value/1000000D).ToString("0.#") + " M"; 
     if (value >= 100000) 
      return (value/1000).ToString("#,0") + " K"; 
     if (value >= 10000) 
      return (value/1000D).ToString("0.#") + " K"; 
     return value.ToString("#,0"); 
    } 
7

Một chút thay đổi v ersion của SLaks code

static string FormatNumber(long 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("0.#k"); 
    } 
    if (num >= 10000) { 
     return (num/1000D).ToString("0.##k"); 
    } 

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

này sẽ trả lại giá trị sau:

123  -> 123 
1234  -> 1,234 
12345  -> 12.35k 
123456  -> 123.4k 
1234567 -> 1.23M 
12345678 -> 12.35M 
123456789 -> 123.5M 
0

Tôi biết đây là một chủ đề rất cũ, nhưng tôi nghĩ rằng một câu trả lời chung chung hơn có thể hữu ích:

ADD: bỏ qua rằng nó phải có được C#, vì vậy ở đây nó được dịch:

//--Formats the number after scaling by factors of 1000, and appends a metric unit prefix (e.g. M for *1000000) 
    //--Mask, Prov are the standard ToString() parameters (after metric scaling has been performed) 
    //--MinPow10 (/Max) should be multipla of 3 and a usually a negative (/Positve) number or zero, if say +9 is used, all is in G or above (/below) 
    //--SwitchLimit usualy 1, but could be say 10 or 100 with few/zero decimals, The limit at which to switch prefix, if say 33 then 33000000->33M but 32900000->32900K 
    static string FormatMetricPrefix(double Input, String Mask ="F2", IFormatProvider Prov=null, int MinPow10 =-24, int MaxPow10 =24, int SwitchLimit =1) { 
     string Prefixes ="yzafpnμm KMGTPEZY"; 
     int idx=9; 
     double tmp=Input; 
     if (Input!=0.0) { 
      if (+24<MaxPow10)MaxPow10=+24; 
      if (MinPow10<-24)MaxPow10=-24; 
      idx=(int)Math.Truncate(9.0+Math.Log(Math.Abs(Input/SwitchLimit))/Math.Log(1000.0)); 
      if (idx<9+(MinPow10/3)) idx=9+(MinPow10/3); // below lower limit 
      if (9+(MaxPow10/3)<idx) idx=9+(MaxPow10/3); // Above upper limit 
      if (idx<=9)tmp *=Math.Pow(1000.0,9-idx); 
      if (9<idx) tmp /=Math.Pow(1000.0,idx-9); 
     } 
     if (Prov==null)Prov=CultureInfo.InvariantCulture; 
     return tmp.ToString(Mask,Prov)+Prefixes.Substring(idx-1,1).Trim(); 
    } 

    static string FormatMetricPrefixF2DK(double Input){return FormatMetricPrefix(Input, Prov:CultureInfo.GetCultureInfo("da-DK"));} 
    static string FormatMetricPrefixF2US(double Input){return FormatMetricPrefix(Input, Prov:CultureInfo.GetCultureInfo("en-US"));} 
    static string FormatMetricPrefixF0DK(double Input){return FormatMetricPrefix(Input, Mask:"F0", MinPow10:0, Prov:CultureInfo.GetCultureInfo("da-DK"),SwitchLimit:100);} 
    static string FormatMetricPrefixF0US(double Input){return FormatMetricPrefix(Input, Mask:"F0", MinPow10:0, Prov:CultureInfo.GetCultureInfo("en-US"),SwitchLimit:100);} 
    static void Main(string[] args) 
    { 
     Console.WriteLine(FormatMetricPrefixF2US(1.234567890E+27)); 
     Console.WriteLine(FormatMetricPrefixF2US(1234567890)); 
     Console.WriteLine(FormatMetricPrefixF2US(0.)); 
     Console.WriteLine(FormatMetricPrefixF2US(0.000000)); 
     Console.WriteLine(FormatMetricPrefixF2US(1.234567890E-26)); 
     Console.WriteLine(FormatMetricPrefixF0US(0.5)); 
     Console.WriteLine(FormatMetricPrefixF0US(2)); 
     Console.WriteLine(FormatMetricPrefixF0US(20000)); 
     Console.WriteLine(FormatMetricPrefixF0US(87654321)); 

    } 

Và điều này là dành cho SQL:

--Formats the number after scaling by factors of 1000, and appends a metric unit prefix (e.g. M for *1000000) 
[email protected], @Cult are the standard FORMAT parameters (after metric scaling has been performed) 
[email protected] (/Max) should be multipla of 3 and a usually a negative (/Positve) number or zero, if say +9 is used, all is in G or above (/below) 
[email protected] usualy 1, but could be say 10 or 100 with few/zero decimals, The limit at which to switch prefix, if say 33 then 33000000->33M but 32900000->32900K 
CREATE function FormatMetricPrefix(@Input float, @Mask Varchar(22)='F2', @Cult Varchar(9)='en-us', @MinPow10 int =-24, @MaxPow10 int =24, @SwitchLimit int=1) returns Varchar(99) as 
Begin 
    Declare @Prefixes Varchar(17)='yzafpnμm KMGTPEZY' 
    Declare @idx int = 9 
    Declare @tmp [email protected] 
    if @Input<>0.0 
    begin 
    if +24<@MaxPow10 set @MaxPow10=+24 --highest limit is y 10^24 
    if @MinPow10<-24 set @MinPow10=-24 --lowest limit is y 10^-24 
    set @idx=9.0+Log(Abs(@input/@SwitchLimit))/Log(1000) 
    If @idx<9+(@MinPow10/3) set @idx=9+(@MinPow10/3) -- below lower limit 
    If 9+(@MaxPow10/3)<@idx set @idx=9+(@MaxPow10/3) --above upper limit 
    if @idx<=9set @[email protected]*POWER(1000.0,[email protected]) 
    if 9<@idx set @[email protected]/POWER(1000.0,@idx-9) 
    end 
    Return FORMAT(@tmp,@mask,@Cult)+LTrim(Substring(@Prefixes,@idx,1)) 
end 
GO 

Và sau đó có lẽ một số hàm bao bọc có liên quan để giảm bớt việc sử dụng, ví dụ:

CREATE function FormatMetricPrefixF2US(@Input float) returns Varchar(99) as 
begin 
    return dbo.FormatMetricPrefix(@Input, default,default,default,default,default) 
end 
GO 
CREATE function FormatMetricPrefixF0US(@Input float) returns Varchar(99) as 
begin 
    return dbo.FormatMetricPrefix(@Input, 'F0' ,default, 0 ,default, 100 ) 
end 
GO 

Và một loạt các thử nghiệm/ví dụ:

 Select 0, dbo.FormatMetricPrefixF2US(1.234567890E+27)+'g' 
union Select 1, dbo.FormatMetricPrefixF2US(1234567890)+'g' 
union Select 2, dbo.FormatMetricPrefixF2US(123456789.0)+'g' 
union Select 3, dbo.FormatMetricPrefixF2US(12345678.90)+'g' 
union Select 4, dbo.FormatMetricPrefixF2US(1234567.890)+'g' 
union Select 5, dbo.FormatMetricPrefixF2US(123456.7890)+'g' 
union Select 6, dbo.FormatMetricPrefixF2US(12345.67890)+'g' 
union Select 7, dbo.FormatMetricPrefixF2US(1234.567890)+'g' 
union Select 8, dbo.FormatMetricPrefixF2US(123.4567890)+'g' 
union Select 9, dbo.FormatMetricPrefixF2US(12.34567890)+'g' 
union Select 10, dbo.FormatMetricPrefixF2US(1.234567890)+'g' 
union Select 11, dbo.FormatMetricPrefixF2US(0.1234567890)+'g' 
union Select 12, dbo.FormatMetricPrefixF2US(0.)+'g' 
union Select 13, dbo.FormatMetricPrefixF2US(0.0)+'g' 
union Select 14, dbo.FormatMetricPrefixF2US(0.00)+'g' 
union Select 15, dbo.FormatMetricPrefixF2US(0.000)+'g' 
union Select 16, dbo.FormatMetricPrefixF2US(0.0000)+'g' 
union Select 17, dbo.FormatMetricPrefixF2US(0.00000)+'g' 
union Select 18, dbo.FormatMetricPrefixF2US(0.000000)+'g' 
union Select 19, dbo.FormatMetricPrefixF2US(1.234567890E-26)+'g' 
union Select 20, dbo.FormatMetricPrefixF0US(0.5) 
union Select 20, dbo.FormatMetricPrefixF0US(2) 
union Select 21, dbo.FormatMetricPrefixF0US(20000) 
union Select 22, dbo.FormatMetricPrefixF0US(87654321) 
0
public static class NumberDisplayHelper 
{ 
    public static string KiloFormat(this decimal number) 
    { 
     return number >= 1000 
      ? $"{(number/1000):0.##}K" 
      : number.ToString(CultureInfo.CurrentCulture); 
    } 

    public static string KiloFormat(this int number) 
    { 
     return number >= 1000 
      ? $"{((decimal)number/1000):0.##}K" 
      : number.ToString(); 
    } 
} 

[Test()] 
public void KiloFormatter() 
{ 
    Assert.AreEqual("900", 900m.KiloFormat()); 
    Assert.AreEqual("1,2K", 1203m.KiloFormat()); 
    Assert.AreEqual("1,59K", 1588.84m.KiloFormat()); 
    Assert.AreEqual("1,52K", 1522.84m.KiloFormat()); 
    Assert.AreEqual("589", 589.KiloFormat()); 
    Assert.AreEqual("1K", 1001.KiloFormat()); 
    Assert.AreEqual("1,46K", 1455.KiloFormat()); 
    Assert.AreEqual("1K", 1000m.KiloFormat()); 
} 
Các vấn đề liên quan